Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // cargo-deps: nom="4.0"
- use std::fs;
- #[macro_use]
- extern crate nom;
- #[derive(Debug)]
- enum JsonValue {
- String(String),
- Number(f64),
- Array(Vec<JsonValue>),
- Object(Vec<(JsonValue, JsonValue)>),
- True,
- False,
- Null,
- }
- // XXX: If we add a second `nom::multispace0` after the `tag!("}")` for some reason the input can
- // never be decided. I'm pretty sure we don't need it, however.
- named!(
- object(&[u8]) -> JsonValue,
- delimited!(
- tuple!(nom::multispace0, tag!("{"), nom::multispace0),
- map!(
- separated_list!(
- tuple!(nom::multispace0, tag!(","), nom::multispace0),
- do_parse!(
- key: string >>
- tuple!(nom::multispace0, tag!(":"), nom::multispace0) >>
- value: value >>
- (key, value))
- ),
- JsonValue::Object
- ),
- tuple!(nom::multispace0, tag!("}"))
- )
- );
- named!(
- array(&[u8]) -> JsonValue,
- ws!(delimited!(tag!("["),
- map!(separated_list!(tuple!(nom::multispace0, tag!(","), nom::multispace0), value), JsonValue::Array),
- tag!("]")))
- );
- named!(value(&[u8]) -> JsonValue, alt!(string | number | object | array | constant ));
- // FIXME: Handle escapes!
- named!(
- string_char(&[u8]) -> char,
- none_of!("\"")
- );
- named!(
- string(&[u8]) -> JsonValue,
- map!(delimited!(tag!("\""), many0!(string_char), tag!("\"")),
- |o| JsonValue::String(o.into_iter().collect()))
- );
- named!(
- number(&[u8]) -> JsonValue,
- map!(nom::double, JsonValue::Number)
- );
- named!(
- constant(&[u8]) -> JsonValue,
- alt!(
- tag!("true") => { |_| JsonValue::True } |
- tag!("false") => { |_| JsonValue::False } |
- tag!("null") => { |_| JsonValue::Null }
- )
- );
- fn main() {
- let contents = fs::read("sample.json").unwrap();
- let sample = nom::types::CompleteByteSlice(&contents);
- let (_, parsed_json) = object(&sample).unwrap();
- println!("{:#?}", parsed_json);
- }
Add Comment
Please, Sign In to add comment