use crate::attribute::ExtendedAttributeList;
use crate::common::{Default, Identifier};
use crate::types::Type;
use crate::Parse;
pub type DictionaryMembers<'a> = Vec<DictionaryMember<'a>>;
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct DictionaryMember<'a> {
pub attributes: Option<ExtendedAttributeList<'a>>,
pub required: Option<crate::term::Required>,
pub type_: Type<'a>,
pub identifier: Identifier<'a>,
pub default: Option<Default<'a>>,
pub semi_colon: crate::term::SemiColon,
}
impl<'a> Parse<'a> for DictionaryMember<'a> {
fn parse(input: &'a str) -> crate::IResult<&'a str, Self> {
let (input, attributes) = <Option<ExtendedAttributeList<'a>>>::parse(input)?;
let (input, required) = <Option<crate::term::Required>>::parse(input)?;
if required.is_some() {
let (input, type_attributes) = <Option<ExtendedAttributeList<'a>>>::parse(input)?;
let (input, type_) = Type::parse(input)?;
let (input, identifier) = Identifier::parse(input)?;
let (input, semi_colon) = <crate::term::SemiColon>::parse(input)?;
let merged_attributes = match (attributes, type_attributes) {
(_, Some(ta)) => Some(ta),
(ma, None) => ma,
};
Ok((
input,
DictionaryMember {
attributes: merged_attributes,
required,
type_,
identifier,
default: None,
semi_colon,
},
))
} else {
let (input, type_) = Type::parse(input)?;
let (input, identifier) = Identifier::parse(input)?;
let (input, default) = <Option<Default<'a>>>::parse(input)?;
let (input, semi_colon) = <crate::term::SemiColon>::parse(input)?;
Ok((
input,
DictionaryMember {
attributes,
required,
type_,
identifier,
default,
semi_colon,
},
))
}
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::Parse;
test!(should_parse_dictionary_member { "required long num;" =>
"";
DictionaryMember;
attributes.is_none();
required.is_some();
identifier.0 == "num";
default.is_none();
});
test!(should_parse_required_with_type_ext_attrs { "required [EnforceRange] unsigned long num;" =>
"";
DictionaryMember;
attributes.is_some();
required.is_some();
identifier.0 == "num";
default.is_none();
});
test!(should_parse_member_attrs_before_required { "[EnforceRange] required unsigned long num;" =>
"";
DictionaryMember;
attributes.is_some();
required.is_some();
identifier.0 == "num";
default.is_none();
});
test!(should_parse_optional_member { "long num;" =>
"";
DictionaryMember;
attributes.is_none();
required.is_none();
identifier.0 == "num";
default.is_none();
});
test!(should_parse_optional_member_with_default { "long num = 5;" =>
"";
DictionaryMember;
attributes.is_none();
required.is_none();
identifier.0 == "num";
default.is_some();
});
test!(should_parse_optional_member_with_attrs { "[Clamp] long num;" =>
"";
DictionaryMember;
attributes.is_some();
required.is_none();
identifier.0 == "num";
default.is_none();
});
}