diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/bin.rs | 5 | ||||
| -rw-r--r-- | src/parser/mod.rs | 3 | ||||
| -rw-r--r-- | src/parser/serialize.rs | 36 | ||||
| -rw-r--r-- | src/rst.pest | 10 |
4 files changed, 46 insertions, 8 deletions
@@ -6,7 +6,7 @@ use structopt::StructOpt; use clap::{_clap_count_exprs, arg_enum}; use quicli::{main, fs::read_file, prelude::Verbosity}; -use self::parser::{RstParser, Rule}; +use self::parser::{RstParser, Rule, serialize::PairsWrap}; arg_enum! { @@ -30,7 +30,8 @@ struct Cli { main!(|args: Cli, log_level: verbosity| { let content = read_file(args.file)?; let parsed = RstParser::parse(Rule::doc, &content)?; + let stdout = std::io::stdout(); match args.format { - Format::json => println!("{}", parsed.to_string()) + Format::json => serde_json::to_writer(stdout, &PairsWrap(parsed))?, } }); diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 2ae47cb..26470e8 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -1,10 +1,11 @@ pub mod token; +pub mod serialize; #[allow(unused_imports)] use pest::consumes_to; #[allow(unused_imports)] use pest::parses_to; -use pest_derive::*; +use pest_derive::Parser; #[derive(Parser)] #[grammar = "rst.pest"] diff --git a/src/parser/serialize.rs b/src/parser/serialize.rs new file mode 100644 index 0000000..260084f --- /dev/null +++ b/src/parser/serialize.rs @@ -0,0 +1,36 @@ +use pest::{RuleType, iterators::{Pair, Pairs}}; +use serde::{ + Serialize, + Serializer, + ser::{ + SerializeSeq, + SerializeStruct, + }, +}; + +pub struct PairsWrap<'i, R>(pub Pairs<'i, R>); +pub struct PairWrap <'i, R>(pub Pair <'i, R>); + +impl<'i, R> Serialize for PairsWrap<'i, R> where R: RuleType { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer { + let mut seq = serializer.serialize_seq(None)?; + for pair in self.0.clone() { + seq.serialize_element(&PairWrap(pair))?; + } + seq.end() + } +} + +impl<'i, R> Serialize for PairWrap<'i, R> where R: RuleType { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer { + let mut state = serializer.serialize_struct("Pair", 3)?; + state.serialize_field("rule", &format!("{:?}", self.0.as_rule()))?; + let tokens: Vec<_> = self.0.clone().tokens().collect(); + if tokens.len() > 2 { + state.serialize_field("inner", &PairsWrap(self.0.clone().into_inner()))?; + } else { + state.serialize_field("content", self.0.as_str())?; + } + state.end() + } +} diff --git a/src/rst.pest b/src/rst.pest index f087c2e..9f92ef7 100644 --- a/src/rst.pest +++ b/src/rst.pest @@ -444,7 +444,7 @@ code = { ticks_2 ~ ( (!"`" ~ nonspacechar)+ | "_" | !ticks_2 ~ "`" | !(sp ~ tick raw_html = { (html_comment | html_block_script | html_tag) } -blank_line = { sp ~ NEWLINE } +blank_line = _{ sp ~ NEWLINE } quoted = { "\"" ~ (!"\"" ~ ANY)* ~ "\"" | @@ -483,16 +483,16 @@ hex_entity = { "&#" ~ ("X"|"x") ~ ('0'..'9' | 'a'..'f' | 'A'..'F')+ ~ ";" } dec_entity = { "&#" ~ ASCII_DIGIT+ ~ ";" } char_entity = { "&" ~ ASCII_ALPHANUMERIC+ ~ ";" } -nonindent_space = { " " | " " | "" } -indent = { "\t" | " " } +nonindent_space = _{ " " | " " | "" } +indent = _{ "\t" | " " } indented_line = { indent ~ line } optionally_indented_line = { indent? ~ line } doctest_line = { ">>> " ~ raw_line } -line = { raw_line } +line = _{ raw_line } -raw_line = { (!NEWLINE ~ ANY)* ~ NEWLINE | (!EOI ~ ANY)+ ~ EOI } +raw_line = _{ (!NEWLINE ~ ANY)* ~ NEWLINE | (!EOI ~ ANY)+ ~ EOI } skip_block = { html_block | |
