diff --git a/examples/include_file_tag.rs b/examples/include_file_tag.rs index 4876b87..6472434 100644 --- a/examples/include_file_tag.rs +++ b/examples/include_file_tag.rs @@ -24,7 +24,7 @@ impl<'a> IncludeParser<'a> { impl<'a> yaml::YamlScalarParser for IncludeParser<'a> { fn parse_scalar(&self, tag: &scanner::TokenType, value: &str) -> Option { if let scanner::TokenType::Tag(ref handle, ref suffix) = *tag { - if *handle == "!" && *suffix == "include" { + if (*handle == "!" || *handle == "yaml-rust.include.prefix") && *suffix == "include" { let mut content = String::new(); return Some(match File::open(self.root.join(value)){ Ok(mut f) => { diff --git a/src/parser.rs b/src/parser.rs index 7d147e7..098464d 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -72,6 +72,7 @@ pub struct Parser { token: Option, anchors: HashMap, anchor_id: usize, + tag_directives: HashMap } @@ -106,6 +107,7 @@ impl> Parser { anchors: HashMap::new(), // valid anchor_id starts from 1 anchor_id: 1, + tag_directives: HashMap::new() } } @@ -335,14 +337,14 @@ impl> Parser { // "found incompatible YAML document")); //} }, - TokenType::TagDirective(..) => { - // TODO add tag directive + TokenType::TagDirective(handle, mut prefix) => { + prefix.pop(); //Remove : + self.tag_directives.insert(handle , prefix); }, _ => break } self.skip(); } - // TODO tag directive Ok(()) } @@ -446,7 +448,19 @@ impl> Parser { TokenType::Scalar(style, v) => { self.pop_state(); self.skip(); - Ok((Event::Scalar(v, style, anchor_id, tag), tok.0)) + + Ok((if let Some(TokenType::Tag(handle, suffix)) = tag{ + let t = self.tag_directives.get(&handle); + Event::Scalar(v, style, anchor_id, Some( + if let Some(s) = t { + TokenType::Tag((*s).clone() , suffix) + } else { + TokenType::Tag(handle , suffix) + } + )) + } else { + Event::Scalar(v, style, anchor_id, tag) + }, tok.0)) }, TokenType::FlowSequenceStart => { self.state = State::FlowSequenceFirstEntry; diff --git a/src/yaml.rs b/src/yaml.rs index 23165d2..af6dc5c 100644 --- a/src/yaml.rs +++ b/src/yaml.rs @@ -645,7 +645,7 @@ a1: &DEFAULT impl YamlScalarParser for HelloTagParser { fn parse_scalar(&self, tag: &TokenType, value: &str) -> Option { if let TokenType::Tag(ref handle, ref suffix) = *tag { - if *handle == "!" && *suffix == "hello" { + if (*handle == "!" || *handle == "yaml-rust.hello.prefix") && *suffix == "hello" { return Some(Yaml::String("Hello ".to_string() + value)) } } @@ -658,8 +658,23 @@ a1: &DEFAULT let parser = HelloTagParser; let mut loader = YamlLoader::new(); loader.register_scalar_parser(&parser); - let out = loader.parse_from_str("- !hello world").unwrap(); + let out = loader.parse_from_str("!hello world").unwrap(); let doc = &out[0]; - assert_eq!(doc[0].as_str().unwrap() , "Hello world") + assert_eq!(doc.as_str().unwrap() , "Hello world") + } + + #[test] + fn test_tag_directive() { + let parser = HelloTagParser; + let mut loader = YamlLoader::new(); + loader.register_scalar_parser(&parser); + let out = loader.parse_from_str( +"%YAML 1.2 +%TAG ! yaml-rust.hello.prefix: +--- +!hello world" + ).unwrap(); + let doc = &out[0]; + assert_eq!(doc.as_str().unwrap() , "Hello world") } }