use picojson::{DefaultConfig, Event, ParseError, PushParser, PushParserHandler};
struct EventCollector {
events: Vec<String>,
}
impl EventCollector {
fn new() -> Self {
Self { events: Vec::new() }
}
}
impl<'a, 'b> PushParserHandler<'a, 'b, ParseError> for EventCollector {
fn handle_event(&mut self, event: Event<'a, 'b>) -> Result<(), ParseError> {
let event_desc = match event {
Event::StartObject => "StartObject".to_string(),
Event::EndObject => "EndObject".to_string(),
Event::StartArray => "StartArray".to_string(),
Event::EndArray => "EndArray".to_string(),
Event::Bool(b) => format!("Bool({})", b),
Event::Null => "Null".to_string(),
Event::EndDocument => "EndDocument".to_string(),
Event::Key(k) => format!("Key({})", k.as_ref()),
Event::String(s) => format!("String({})", s.as_ref()),
Event::Number(n) => format!("Number({})", n.as_str()),
};
self.events.push(event_desc);
Ok(())
}
}
#[test]
fn test_string_with_actual_escapes() {
let json_string = "{\"message\": \"Hello\\nWorld\\t!\"}";
let json = json_string.as_bytes();
let handler = EventCollector::new();
let mut buffer = [0u8; 256];
let mut parser = PushParser::<_, DefaultConfig>::new(handler, &mut buffer);
parser.write(json).unwrap();
let handler = parser.finish::<ParseError>().unwrap();
let expected = vec![
"StartObject".to_string(),
"Key(message)".to_string(),
"String(Hello\nWorld\t!)".to_string(),
"EndObject".to_string(),
"EndDocument".to_string(),
];
assert_eq!(handler.events, expected);
}
#[test]
fn test_quote_escape() {
let json_string = r#"{"test": "quote\"here"}"#;
let json = json_string.as_bytes();
let handler = EventCollector::new();
let mut buffer = [0u8; 256];
let mut parser = PushParser::<_, DefaultConfig>::new(handler, &mut buffer);
parser.write(json).unwrap();
let handler = parser.finish::<ParseError>().unwrap();
let expected = vec![
"StartObject".to_string(),
"Key(test)".to_string(),
"String(quote\"here)".to_string(),
"EndObject".to_string(),
"EndDocument".to_string(),
];
assert_eq!(handler.events, expected);
}
#[test]
fn test_escaped_key_with_newline() {
let json_string = r#"{"ke\\ny": "value"}"#;
let json = json_string.as_bytes();
let handler = EventCollector::new();
let mut buffer = [0u8; 256];
let mut parser = PushParser::<_, DefaultConfig>::new(handler, &mut buffer);
parser.write(json).unwrap();
let handler = parser.finish::<ParseError>().unwrap();
let expected = vec![
"StartObject".to_string(),
"Key(ke\\ny)".to_string(),
"String(value)".to_string(),
"EndObject".to_string(),
"EndDocument".to_string(),
];
assert_eq!(handler.events, expected);
}
#[test]
fn test_actual_key_escape_sequence() {
let json_string = r#"{"ke\ny": "value"}"#; let json = json_string.as_bytes();
let handler = EventCollector::new();
let mut buffer = [0u8; 256];
let mut parser = PushParser::<_, DefaultConfig>::new(handler, &mut buffer);
parser.write(json).unwrap();
let handler = parser.finish::<ParseError>().unwrap();
let expected = vec![
"StartObject".to_string(),
"Key(ke\ny)".to_string(),
"String(value)".to_string(),
"EndObject".to_string(),
"EndDocument".to_string(),
];
assert_eq!(handler.events, expected);
}
#[test]
fn test_unicode_escapes() {
let json = br#"["\u0041\u0042\u0043"]"#;
let mut buffer = [0u8; 64];
let handler = EventCollector::new();
let mut parser = PushParser::<_, DefaultConfig>::new(handler, &mut buffer);
parser.write(json).unwrap();
let handler = parser.finish::<ParseError>().unwrap();
let expected = vec![
"StartArray".to_string(),
"String(ABC)".to_string(), "EndArray".to_string(),
"EndDocument".to_string(),
];
assert_eq!(handler.events, expected);
}
#[test]
fn test_escaped_key_with_quote() {
let json_string = r#"{"quo\"te": "data"}"#;
let json = json_string.as_bytes();
let handler = EventCollector::new();
let mut buffer = [0u8; 256];
let mut parser = PushParser::<_, DefaultConfig>::new(handler, &mut buffer);
parser.write(json).unwrap();
let handler = parser.finish::<ParseError>().unwrap();
let expected = vec![
"StartObject".to_string(),
"Key(quo\"te)".to_string(),
"String(data)".to_string(),
"EndObject".to_string(),
"EndDocument".to_string(),
];
assert_eq!(handler.events, expected);
}