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
use nom::{do_parse, error::VerboseError, named, opt, preceded, tag, take_till, Err, IResult}; use std::borrow::Cow; use std::fmt; use crate::{parse::parse_name, Parse, ParseError}; #[derive(Debug, PartialEq, Clone)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "typed-builder", derive(typed_builder::TypedBuilder))] pub struct Parameter<'a> { #[cfg_attr(feature = "typed-builder", builder(setter(into)))] pub name: Cow<'a, str>, #[cfg_attr( feature = "typed-builder", builder(default, setter(into, strip_option)) )] pub value: Option<Cow<'a, str>>, } impl<'a> fmt::Display for Parameter<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if let Some(value) = &self.value { write!(f, "{}={}", self.name, value) } else { write!(f, "{}", self.name) } } } impl<'a> Parse<'a> for Parameter<'a> { fn parse(input: &'a str) -> IResult<&'a str, Self, ParseError> { match parse_parameter(input) { Ok(item) => Ok(item), Err(Err::Failure(err)) => Err(Err::Failure(ParseError(err))), Err(Err::Error(err)) => Err(Err::Error(ParseError(err))), Err(Err::Incomplete(item)) => Err(Err::Incomplete(item)), } } } named!(pub parse_parameter<&str, Parameter, VerboseError<&str>>, do_parse!( name: parse_name >> value: opt!(preceded!(tag!("="), parse_parameter_value)) >> (Parameter { name, value }) )); named!(parse_parameter_value<&str, Cow<str>, VerboseError<&str>>, do_parse!( value: take_till!(|x| ":;".contains(x)) >> (value.into()) ));