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
use crate::parsers::useless::{is_not_block_ending, non_useless}; use crate::structure::{Selector, Selectors}; use nom::branch::alt; use nom::bytes::complete::is_not; use nom::character::complete::char; use nom::combinator::map; use nom::multi::separated_list1; use nom::sequence::preceded; use nom::IResult; pub fn parse_selectors(input: &str) -> IResult<&str, Selectors> { map( is_not_block_ending(separated_list1(char(','), non_useless(parse_selector))), |selectors| selectors.into(), )(input) } pub fn parse_selector(input: &str) -> IResult<&str, Selector> { alt((parse_id, parse_class, parse_tag))(input) } pub fn parse_id(input: &str) -> IResult<&str, Selector> { map(preceded(char('#'), is_not(",{")), |i: &str| { Selector::Id(i.trim().into()) })(input) } pub fn parse_class(input: &str) -> IResult<&str, Selector> { map(preceded(char('.'), is_not(",{")), |i: &str| { Selector::Class(i.trim().into()) })(input) } pub fn parse_tag(input: &str) -> IResult<&str, Selector> { map(is_not(",{"), |i: &str| Selector::Tag(i.trim().into()))(input) } #[cfg(test)] mod test { use crate::parsers::selector::{parse_selector, parse_selectors}; use crate::structure::Selector; #[test] fn test_selector() { assert_eq!( parse_selector("#some_id"), Ok(("", Selector::Id("some_id".into()))) ); assert_eq!( parse_selector(".some_class"), Ok(("", Selector::Class("some_class".into()))) ); assert_eq!( parse_selector("input"), Ok(("", Selector::Tag("input".into()))) ); } #[test] fn test_selectors() { assert_eq!( parse_selectors("#some_id, .some_class, input"), Ok(( "", vec![ Selector::Id("some_id".into()), Selector::Class("some_class".into()), Selector::Tag("input".into()) ] .into() )) ); } }