1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use sawp::error::{Error, ErrorKind, Result};
use sawp::parser::{Direction, Parse};
use sawp::probe::Probe;
use sawp::protocol::Protocol;
use serde_json::{Deserializer, Value};
#[derive(Debug)]
pub struct Json {}
#[derive(Debug, PartialEq)]
pub struct Message {
pub value: Value,
}
impl Message {
pub fn new(value: Value) -> Self {
Self { value }
}
}
impl Protocol<'_> for Json {
type Message = Message;
fn name() -> &'static str {
"json"
}
}
impl<'a> Parse<'a> for Json {
fn parse(
&self,
input: &'a [u8],
_direction: Direction,
) -> Result<(&'a [u8], Option<Self::Message>)> {
let mut stream = Deserializer::from_slice(input).into_iter::<Value>();
match stream.next() {
Some(Ok(value)) => Ok((&input[stream.byte_offset()..], Some(Message::new(value)))),
_ => Err(Error::new(ErrorKind::InvalidData)),
}
}
}
impl<'a> Probe<'a> for Json {}
#[cfg(test)]
mod tests {
use super::*;
use rstest::rstest;
use sawp::error::{Error, ErrorKind, Result};
use sawp::probe::Status;
use serde_json::json;
#[rstest(
input,
expected,
case::empty(b"", Err(Error::new(ErrorKind::InvalidData))),
case::singlequote(b"''", Err(Error::new(ErrorKind::InvalidData))),
case::incomplete(b"{\"a\":", Err(Error::new(ErrorKind::InvalidData))),
case::number(b"1234", Ok((0, Some(Message::new(json!(1234)))))),
case::null(b"null", Ok((0, Some(Message::new(json!(null)))))),
case::bool_true(b"true", Ok((0, Some(Message::new(json!(true)))))),
case::bool_false(b"false", Ok((0, Some(Message::new(json!(false)))))),
case::empty_obj(b"{}", Ok((0, Some(Message::new(json!({})))))),
case::empty_list(b"[]", Ok((0, Some(Message::new(json!([])))))),
case::empty_string(b"\"\"", Ok((0, Some(Message::new(json!("")))))),
case::object(b"{\"a\":\"b\"}", Ok((0, Some(Message::new(json!({"a": "b"})))))),
case::list(b"[\"a\", \"b\"]", Ok((0, Some(Message::new(json!(["a", "b"])))))),
case::whitespace(b"\n\t{\n\r\n\"a\": \t\"b\"\n}", Ok((0, Some(Message::new(json!({"a": "b"})))))),
case::multi(b"{}[1]", Ok((3, Some(Message::new(json!({})))))),
)]
fn test_parse(input: &[u8], expected: Result<(usize, Option<<Json as Protocol>::Message>)>) {
let json = Json {};
assert_eq!(
expected,
json.parse(input, Direction::Unknown)
.map(|(left, msg)| (left.len(), msg)),
);
}
#[rstest(
input,
expected,
case::empty(b"", Status::Unrecognized),
case::incomplete(b"{\"a\":", Status::Unrecognized),
case::number(b"1234", Status::Recognized)
)]
fn test_probe(input: &[u8], expected: Status) {
let json = Json {};
assert_eq!(expected, json.probe(input, Direction::Unknown));
}
}