-
Notifications
You must be signed in to change notification settings - Fork 0
/
check_json.rs
59 lines (47 loc) · 1.64 KB
/
check_json.rs
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
use std::io::Read;
use textparse::{
components::{AnyChar, Char, Digit, Eos, Items, NonEmpty, Not, Str, While, Whitespace},
Parse, Parser, Position, Span,
};
fn main() -> anyhow::Result<()> {
let mut text = String::new();
std::io::stdin().read_to_string(&mut text)?;
let mut parser = Parser::new(&text);
if parser.parse::<(JsonValue, Eos)>().is_some() {
println!("OK: the input string is a JSON text.");
} else {
println!("Error: {}", parser.into_parse_error().file_path("<STDIN>"));
}
Ok(())
}
#[derive(Clone, Span, Parse)]
struct JsonValue(WithoutWhitespaces<JsonValueInner>);
#[derive(Clone, Span, Parse)]
#[parse(name = "a JSON value")]
enum JsonValueInner {
Null(JsonNull),
String(JsonString),
Number(JsonNumber),
Array(JsonArray),
Object(JsonObject),
}
#[derive(Clone, Span, Parse)]
struct JsonNull(Str<'n', 'u', 'l', 'l'>);
#[derive(Clone, Span, Parse)]
#[parse(name = "a JSON string")]
struct JsonString(Char<'"'>, While<(Not<Char<'"'>>, AnyChar)>, Char<'"'>);
#[derive(Clone, Span, Parse)]
#[parse(name = "a JSON number")]
struct JsonNumber(NonEmpty<While<Digit>>);
#[derive(Clone, Span, Parse)]
#[parse(name = "a JSON array")]
struct JsonArray(Char<'['>, Csv<JsonValue>, Char<']'>);
#[derive(Clone, Span, Parse)]
#[parse(name = "a JSON object")]
struct JsonObject(Char<'{'>, Csv<JsonObjectItem>, Char<'}'>);
#[derive(Clone, Span, Parse)]
struct JsonObjectItem(WithoutWhitespaces<JsonString>, Char<':'>, JsonValue);
#[derive(Clone, Span, Parse)]
struct Csv<T>(Items<T, Char<','>>);
#[derive(Clone, Span, Parse)]
struct WithoutWhitespaces<T>(While<Whitespace>, T, While<Whitespace>);