1#![warn(clippy::redundant_pub_crate)]
2
3use match_all::MatchAll;
4use matcher::MatchTokensBuilder;
5use proc_macro2::TokenStream;
6use syn::Result;
7use token_entry::{FindAllStringBuilder, ParseStreamEx, Source, TokenStringBuilder};
8
9pub use matcher::Matcher;
10pub use transcriber::Transcriber;
11
12#[macro_use]
13mod utils;
14
15pub mod match_all;
16mod matcher;
17mod text;
18mod token_entry;
19mod transcriber;
20
21#[derive(Clone, Debug)]
23pub struct Rule {
24 from: Matcher,
25 to: Transcriber,
26 nest: bool,
27}
28
29impl Rule {
30 pub fn new(from: Matcher, mut to: Transcriber) -> Result<Self> {
34 to.attach(&from.0)?;
35 Ok(Rule {
36 from,
37 to,
38 nest: false,
39 })
40 }
41 pub fn nest(self, yes: bool) -> Self {
61 Self { nest: yes, ..self }
62 }
63
64 pub fn replace_all(&self, input: &str) -> Result<String> {
69 let (source, input) = Source::from_str(input)?;
70 let mut b = TokenStringBuilder::new(&source);
71 self.from
72 .find_all(input, 0)
73 .apply_string(self, &mut FindAllStringBuilder::new(&mut b, 0));
74 Ok(b.s)
75 }
76
77 pub fn replace_all_tokens(&self, input: TokenStream) -> TokenStream {
79 self.from
80 .find_all(input.clone(), 0)
81 .apply_tokens(&mut 0, input, self)
82 }
83
84 pub fn match_all<'a>(&'a self, input: &'a str) -> Result<MatchAll<'a>> {
86 let (source, input) = Source::from_str(input)?;
87 Ok(self.from.match_all(source, input, self))
88 }
89
90 pub fn apply(&self, input: &str) -> Result<String> {
92 let (source, input) = Source::from_str(input)?;
93 ParseStreamEx::parse_from_tokens(input, 0, |input: &mut ParseStreamEx| {
94 let m = self.from.try_match(input)?;
95 let mut b = TokenStringBuilder::new(&source);
96 self.to.apply_string(&m, self, usize::MAX, &mut b);
97 Ok(b.s)
98 })
99 }
100
101 pub fn apply_tokens(&self, input: TokenStream) -> Result<TokenStream> {
103 ParseStreamEx::parse_from_tokens(input, 0, |input: &mut ParseStreamEx| {
104 self.apply_tokens_parser(input)
105 })
106 }
107 fn apply_tokens_parser(&self, input: &mut ParseStreamEx) -> Result<TokenStream> {
108 let m = self.from.try_match(input)?;
109 let mut tokens = TokenStream::new();
110 let mut b = MatchTokensBuilder {
111 tokens: &mut tokens,
112 rule: self,
113 tes_len: usize::MAX,
114 };
115 self.to.apply_tokens_to(&m, &mut b);
116 Ok(tokens)
117 }
118}