1mod ast;
19mod eval;
20mod expr;
21mod parse;
22
23use ast::Entry;
24use eval::Eval;
25pub use eval::Sample;
26use parse::parse_query;
27use rand::SeedableRng;
28use rand_pcg::Pcg64 as Pcg;
29
30macro_rules! regex {
31 ($re:literal $(,)?) => {{
32 static RE: std::sync::OnceLock<regex::Regex> = std::sync::OnceLock::new();
33 RE.get_or_init(|| regex::Regex::new($re).unwrap())
34 }};
35}
36pub(crate) use regex;
37
38pub fn run_query(input: &str) -> Result<Vec<Sample>, Error> {
40 let mut state = State::new();
41 state.run_query(input)
42}
43
44#[derive(Debug, Clone)]
46pub struct State {
47 rng: Pcg,
48 data: Vec<(usize, Entry)>,
49}
50
51impl State {
52 pub fn new() -> Self {
56 Self::from_rng(Pcg::from_entropy())
57 }
58 pub fn with_seed(seed: u64) -> Self {
60 Self::from_rng(Pcg::seed_from_u64(seed))
61 }
62 fn from_rng(rng: Pcg) -> Self {
63 Self {
64 rng,
65 data: Vec::new(),
66 }
67 }
68}
69
70impl Default for State {
71 fn default() -> Self {
72 Self::new()
73 }
74}
75
76impl State {
77 pub fn run_query(&mut self, input: &str) -> Result<Vec<Sample>, Error> {
81 let mut ast = parse_query(input)?;
82 if !self.data.is_empty() {
83 let mut entries = std::mem::take(&mut self.data);
84 let last_id = entries.last().map(|(id, _)| *id).unwrap_or(0);
85
86 entries.reserve(ast.root.entries.len());
87 for (id, e) in ast.root.entries {
88 entries.push((id + last_id + 1, e));
89 }
90 debug_assert!(entries.windows(2).all(|w| w[0].0 + 1 == w[1].0));
91 ast.root.entries = entries;
92 }
93 let res = ast.eval(&mut self.rng);
94 let v = match res {
95 eval::EvalRes::Emtpy => vec![],
96 eval::EvalRes::Single(s) => vec![s],
97 eval::EvalRes::Many(v) => v,
98 };
99 Ok(v)
100 }
101
102 fn push_entry(&mut self, entry: Entry) {
103 let id = self.data.len();
104 self.data.push((id, entry));
105 }
106
107 pub fn add_data(&mut self, entry: &str) {
109 self.push_entry(Entry::data(entry.trim()));
110 }
111
112 pub fn add_entry(&mut self, entry: &str) -> Result<(), Error> {
114 let entry = Entry::parse(entry.trim())?;
115 self.push_entry(entry);
116 Ok(())
117 }
118}
119
120#[derive(Debug)]
122pub enum Error {
123 Options(String),
125 Expr(String),
127 ParseQuery(String),
129}
130
131impl std::fmt::Display for Error {
132 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
133 match self {
134 Error::Options(e) => write!(f, "options: {e}"),
135 Error::Expr(e) => write!(f, "expresions: {e}"),
136 Error::ParseQuery(e) => write!(f, "query structure: {e}"),
137 }
138 }
139}
140
141impl std::error::Error for Error {}