use cssparser::Parser;
use crate::document::NodeId;
use crate::error::*;
use crate::parsers::Parse;
#[derive(Debug, Clone, PartialEq)]
pub enum Iri {
None,
Resource(Box<NodeId>),
}
impl Iri {
pub fn get(&self) -> Option<&NodeId> {
match *self {
Iri::None => None,
Iri::Resource(ref f) => Some(f),
}
}
}
impl Parse for Iri {
fn parse<'i>(parser: &mut Parser<'i, '_>) -> Result<Iri, ParseError<'i>> {
if parser
.try_parse(|i| i.expect_ident_matching("none"))
.is_ok()
{
Ok(Iri::None)
} else {
let loc = parser.current_source_location();
let url = parser.expect_url()?;
let node_id =
NodeId::parse(&url).map_err(|e| loc.new_custom_error(ValueErrorKind::from(e)))?;
Ok(Iri::Resource(Box::new(node_id)))
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parses_none() {
assert_eq!(Iri::parse_str("none").unwrap(), Iri::None);
}
#[test]
fn parses_url() {
assert_eq!(
Iri::parse_str("url(#bar)").unwrap(),
Iri::Resource(Box::new(NodeId::Internal("bar".to_string())))
);
assert_eq!(
Iri::parse_str("url(foo#bar)").unwrap(),
Iri::Resource(Box::new(NodeId::External(
"foo".to_string(),
"bar".to_string()
)))
);
assert_eq!(
Iri::parse_str("url(#bar").unwrap(),
Iri::Resource(Box::new(NodeId::Internal("bar".to_string())))
);
assert_eq!(
Iri::parse_str("url(foo#bar").unwrap(),
Iri::Resource(Box::new(NodeId::External(
"foo".to_string(),
"bar".to_string()
)))
);
assert!(Iri::parse_str("").is_err());
assert!(Iri::parse_str("foo").is_err());
assert!(Iri::parse_str("url(foo)bar").is_err());
}
}