1use cssparser::Parser;
4
5use crate::document::NodeId;
6use crate::error::*;
7use crate::parsers::Parse;
8
9#[derive(Debug, Clone, PartialEq)]
16pub enum Iri {
17 None,
18 Resource(Box<NodeId>),
19}
20
21impl Iri {
22 pub fn get(&self) -> Option<&NodeId> {
24 match *self {
25 Iri::None => None,
26 Iri::Resource(ref f) => Some(f),
27 }
28 }
29}
30
31impl Parse for Iri {
32 fn parse<'i>(parser: &mut Parser<'i, '_>) -> Result<Iri, ParseError<'i>> {
33 if parser
34 .try_parse(|i| i.expect_ident_matching("none"))
35 .is_ok()
36 {
37 Ok(Iri::None)
38 } else {
39 let loc = parser.current_source_location();
40 let url = parser.expect_url()?;
41 let node_id =
42 NodeId::parse(&url).map_err(|e| loc.new_custom_error(ValueErrorKind::from(e)))?;
43
44 Ok(Iri::Resource(Box::new(node_id)))
45 }
46 }
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52
53 #[test]
54 fn parses_none() {
55 assert_eq!(Iri::parse_str("none").unwrap(), Iri::None);
56 }
57
58 #[test]
59 fn parses_url() {
60 assert_eq!(
61 Iri::parse_str("url(#bar)").unwrap(),
62 Iri::Resource(Box::new(NodeId::Internal("bar".to_string())))
63 );
64
65 assert_eq!(
66 Iri::parse_str("url(foo#bar)").unwrap(),
67 Iri::Resource(Box::new(NodeId::External(
68 "foo".to_string(),
69 "bar".to_string()
70 )))
71 );
72
73 assert_eq!(
75 Iri::parse_str("url(#bar").unwrap(),
76 Iri::Resource(Box::new(NodeId::Internal("bar".to_string())))
77 );
78 assert_eq!(
79 Iri::parse_str("url(foo#bar").unwrap(),
80 Iri::Resource(Box::new(NodeId::External(
81 "foo".to_string(),
82 "bar".to_string()
83 )))
84 );
85
86 assert!(Iri::parse_str("").is_err());
87 assert!(Iri::parse_str("foo").is_err());
88 assert!(Iri::parse_str("url(foo)bar").is_err());
89 }
90}