tabnas_transduce/source/
mod.rs1pub mod capability;
19pub mod guard;
20pub mod lines;
21pub mod parser;
22pub(crate) mod rule_events;
23
24pub use guard::Guarded;
25pub use lines::{LineFormat, LinesSource, DEFAULT_CHUNK_BYTES};
26pub use parser::ParserSource;
27
28use crate::error::Fail;
29use crate::event::{JsonEvent, Number};
30use crate::limits::AbortFlag;
31use crate::selector::Selector;
32use crate::sink::{Flow, Sink};
33
34#[derive(Clone, Debug, PartialEq, Eq)]
36pub enum SourceMode {
37 Materialize,
39 Incremental { prune: Prune },
42}
43
44#[derive(Clone, Debug, PartialEq, Eq)]
48pub enum Prune {
49 Never,
50 Under(Selector),
53 AllArrays,
54}
55
56const CANCEL: &str = "cancel";
59
60pub(crate) fn engine_failure(error: &tabnas::TabnasError, abort: &AbortFlag) -> Fail {
68 if error.code != CANCEL {
69 return Fail::from_tabnas(error);
70 }
71 if abort.is_aborted() {
72 return Fail::aborted();
73 }
74 let mut fail = Fail::from_tabnas(error);
75 fail.message = format!(
76 "the grammar stopped the parse with a guard of its own ({}: {}); a grammar may refuse \
77 nesting or size below this crate's Limits",
78 error.code,
79 error.detail.trim_end()
80 );
81 fail
82}
83
84pub trait Source {
86 fn run(self, sink: &mut dyn Sink) -> Result<Flow, Fail>;
90}
91
92pub struct ValueSource<'v>(pub &'v tabnas::Value);
94
95impl Source for ValueSource<'_> {
96 fn run(self, sink: &mut dyn Sink) -> Result<Flow, Fail> {
97 if walk_value(self.0, sink)? == Flow::Stop {
98 return Ok(Flow::Stop);
99 }
100 sink.event(JsonEvent::End)
101 }
102}
103
104pub fn walk_value(value: &tabnas::Value, sink: &mut dyn Sink) -> Result<Flow, Fail> {
109 macro_rules! send {
110 ($ev:expr) => {
111 if sink.event($ev)? == Flow::Stop {
112 return Ok(Flow::Stop);
113 }
114 };
115 }
116 match value {
117 tabnas::Value::Undefined | tabnas::Value::Null => send!(JsonEvent::Null),
118 tabnas::Value::Bool(b) => send!(JsonEvent::Bool(*b)),
119 tabnas::Value::Number(n) => send!(JsonEvent::Number(Number::new(*n))),
120 tabnas::Value::String(s) => send!(JsonEvent::String(s)),
121 tabnas::Value::Text(t) => send!(JsonEvent::String(&t.string)),
122 tabnas::Value::Array(items) => {
123 send!(JsonEvent::ArrayStart);
124 for item in items.iter() {
125 if walk_value(item, sink)? == Flow::Stop {
126 return Ok(Flow::Stop);
127 }
128 }
129 send!(JsonEvent::ArrayEnd);
130 }
131 tabnas::Value::ListRef(list) => {
132 send!(JsonEvent::ArrayStart);
133 for item in list.value.iter() {
134 if walk_value(item, sink)? == Flow::Stop {
135 return Ok(Flow::Stop);
136 }
137 }
138 send!(JsonEvent::ArrayEnd);
139 }
140 tabnas::Value::Object(members) => {
141 send!(JsonEvent::ObjectStart);
142 for (k, v) in members.iter() {
143 send!(JsonEvent::Key(k));
144 if walk_value(v, sink)? == Flow::Stop {
145 return Ok(Flow::Stop);
146 }
147 }
148 send!(JsonEvent::ObjectEnd);
149 }
150 tabnas::Value::MapRef(map) => {
151 send!(JsonEvent::ObjectStart);
152 for (k, v) in map.value.iter() {
153 send!(JsonEvent::Key(k));
154 if walk_value(v, sink)? == Flow::Stop {
155 return Ok(Flow::Stop);
156 }
157 }
158 send!(JsonEvent::ObjectEnd);
159 }
160 }
161 Ok(Flow::Continue)
162}
163
164#[cfg(test)]
165mod tests {
166 use super::*;
167 use crate::event::OwnedJsonEvent;
168
169 #[test]
170 fn a_value_walks_in_document_order() {
171 let v = tabnas_json::parse(r#"{"a":[1,"x"],"b":null}"#).unwrap();
172 let mut rec: Vec<OwnedJsonEvent> = Vec::new();
173 ValueSource(&v).run(&mut rec).unwrap();
174 assert_eq!(
175 rec,
176 vec![
177 OwnedJsonEvent::ObjectStart,
178 OwnedJsonEvent::Key("a".into()),
179 OwnedJsonEvent::ArrayStart,
180 OwnedJsonEvent::Number {
181 value: 1.0,
182 lexeme: None
183 },
184 OwnedJsonEvent::String("x".into()),
185 OwnedJsonEvent::ArrayEnd,
186 OwnedJsonEvent::Key("b".into()),
187 OwnedJsonEvent::Null,
188 OwnedJsonEvent::ObjectEnd,
189 OwnedJsonEvent::End,
190 ]
191 );
192 }
193}