-
-
Save ducaale/5d3a3df08a39d128eedab362aac34850 to your computer and use it in GitHub Desktop.
Using nom for parsing Json path
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "nom-test" | |
version = "0.1.0" | |
authors = ["ducaale <sharaf.13@hotmail.com>"] | |
edition = "2018" | |
[dependencies] | |
nom="6" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use nom::{IResult, combinator::map}; | |
use nom::combinator::recognize; | |
use nom::bytes::complete::{take_while, take_till1, tag}; | |
use nom::sequence::{preceded, pair, delimited}; | |
use nom::character::complete::{satisfy, char}; | |
use nom::multi::many0; | |
use nom::branch::alt; | |
fn main() { | |
let input = "key.abc[hello.everyone.3.2][].world"; | |
json_path(input).unwrap(); | |
println!("Hello, world!"); | |
} | |
fn start_identifier(c: char) -> bool { | |
c.is_ascii_alphabetic() || c == '$' || c == '_' | |
} | |
fn part_identifier(c: char) -> bool { | |
c.is_ascii_alphanumeric() || c == '$' || c == '_' | |
} | |
fn valid_identifier(input: &str) -> IResult<&str, &str> { | |
recognize( | |
pair( | |
satisfy(start_identifier), | |
take_while(part_identifier) | |
) | |
) | |
(input) | |
} | |
fn dot_access(input: &str) -> IResult<&str, &str> { | |
preceded(char('.'), valid_identifier)(input) | |
} | |
fn bracket_access(input: &str) -> IResult<&str, &str> { | |
delimited(char('['), take_till1(|c| c == ']'), char(']'))(input) | |
} | |
fn array_access(input: &str) -> IResult<&str, &str> { | |
tag("[]")(input) | |
} | |
fn json_path(input: &str) -> IResult<&str, Vec<&str>> { | |
let parser = pair( | |
valid_identifier, | |
many0(alt((dot_access, bracket_access, array_access))) | |
); | |
map(parser, |(head, mut tail)| { | |
let mut t = vec![head]; | |
t.append(&mut tail); | |
t | |
})(input) | |
} | |
#[test] | |
fn test_bool() { | |
let input = "key.abc[hello\\=world][].world"; | |
assert_eq!( | |
json_path(input), | |
Ok(("", vec!["key", "abc", "hello\\=world", "[]", "world"])) | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment