use super::Handler;
use crate::{error, path::Path, streamer::Token};
use std::{
any::Any,
collections::VecDeque,
str::{self, FromStr},
};
#[derive(Debug)]
pub struct Indexer {
stored: VecDeque<(Option<String>, Token)>,
use_path: bool,
}
impl Default for Indexer {
fn default() -> Self {
Self {
stored: VecDeque::new(),
use_path: false,
}
}
}
impl FromStr for Indexer {
type Err = error::Handler;
fn from_str(input: &str) -> Result<Self, Self::Err> {
let splitted: Vec<_> = input.split(',').collect();
match splitted.len() {
0 => Ok(Self::default()),
1 => Ok(Self::default()
.set_use_path(FromStr::from_str(splitted[0]).map_err(error::Handler::new)?)),
_ => Err(error::Handler::new("Failed to parse")),
}
}
}
impl Handler for Indexer {
fn start(
&mut self,
path: &Path,
_matcher_idx: usize,
token: Token,
) -> Result<Option<Vec<u8>>, error::Handler> {
self.stored.push_back((
if self.use_path {
Some(path.to_string())
} else {
None
},
token,
));
Ok(None)
}
fn end(
&mut self,
path: &Path,
matcher_idx: usize,
token: Token,
) -> Result<Option<Vec<u8>>, error::Handler> {
self.start(path, matcher_idx, token) }
fn as_any(&self) -> &dyn Any {
self
}
}
impl Indexer {
pub fn new() -> Self {
Self::default()
}
pub fn set_use_path(mut self, use_path: bool) -> Self {
self.use_path = use_path;
self
}
pub fn pop(&mut self) -> Option<(Option<String>, Token)> {
self.stored.pop_front()
}
}
#[cfg(test)]
mod tests {
use super::Indexer;
use crate::{
handler::{Buffer, Group},
matcher::Simple,
strategy::{Strategy, Trigger},
streamer::{ParsedKind, Token},
};
use std::sync::{Arc, Mutex};
#[test]
fn indexer_handler() {
let mut trigger = Trigger::new();
let indexer_handler = Arc::new(Mutex::new(Indexer::new()));
let buffer_handler = Arc::new(Mutex::new(Buffer::default()));
let matcher_all = Simple::new(r#"{"elements"}"#).unwrap();
let matcher_elements = Simple::new(r#"{"elements"}[]"#).unwrap();
trigger.add_matcher(Box::new(matcher_all), indexer_handler.clone());
trigger.add_matcher(
Box::new(matcher_elements),
Arc::new(Mutex::new(
Group::new()
.add_handler(indexer_handler.clone())
.add_handler(buffer_handler.clone()),
)),
);
trigger.process(br#"{"elements": [1, 2, 3, 4]}"#).unwrap();
let mut guard = indexer_handler.lock().unwrap();
assert_eq!(
guard.pop().unwrap(),
(None, Token::Start(13, ParsedKind::Arr))
);
assert_eq!(
guard.pop().unwrap(),
(None, Token::Start(14, ParsedKind::Num))
);
assert_eq!(
guard.pop().unwrap(),
(None, Token::End(15, ParsedKind::Num))
);
assert_eq!(
guard.pop().unwrap(),
(None, Token::Start(17, ParsedKind::Num))
);
assert_eq!(
guard.pop().unwrap(),
(None, Token::End(18, ParsedKind::Num))
);
assert_eq!(
guard.pop().unwrap(),
(None, Token::Start(20, ParsedKind::Num))
);
assert_eq!(
guard.pop().unwrap(),
(None, Token::End(21, ParsedKind::Num))
);
assert_eq!(
guard.pop().unwrap(),
(None, Token::Start(23, ParsedKind::Num))
);
assert_eq!(
guard.pop().unwrap(),
(None, Token::End(24, ParsedKind::Num))
);
assert_eq!(
guard.pop().unwrap(),
(None, Token::End(25, ParsedKind::Arr))
);
let mut guard = buffer_handler.lock().unwrap();
assert_eq!(guard.pop().unwrap(), (None, vec![b'1']));
assert_eq!(guard.pop().unwrap(), (None, vec![b'2']));
assert_eq!(guard.pop().unwrap(), (None, vec![b'3']));
assert_eq!(guard.pop().unwrap(), (None, vec![b'4']));
}
}