Skip to content

Commit

Permalink
Parse tag directives
Browse files Browse the repository at this point in the history
  • Loading branch information
DeltaEvo committed Jun 25, 2017
1 parent 09595a3 commit 739f8bd
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 8 deletions.
2 changes: 1 addition & 1 deletion examples/include_file_tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<yaml::Yaml> {
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) => {
Expand Down
22 changes: 18 additions & 4 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub struct Parser<T> {
token: Option<Token>,
anchors: HashMap<String, usize>,
anchor_id: usize,
tag_directives: HashMap<String, String>
}


Expand Down Expand Up @@ -104,6 +105,7 @@ impl<T: Iterator<Item=char>> Parser<T> {
anchors: HashMap::new(),
// valid anchor_id starts from 1
anchor_id: 1,
tag_directives: HashMap::new()
}
}

Expand Down Expand Up @@ -344,14 +346,14 @@ impl<T: Iterator<Item=char>> Parser<T> {
// "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(())
}

Expand Down Expand Up @@ -455,7 +457,19 @@ impl<T: Iterator<Item=char>> Parser<T> {
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;
Expand Down
21 changes: 18 additions & 3 deletions src/yaml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ c: ~
impl YamlScalarParser for HelloTagParser {
fn parse_scalar(&self, tag: &TokenType, value: &str) -> Option<Yaml> {
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))
}
}
Expand All @@ -709,8 +709,23 @@ c: ~
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")
}
}

0 comments on commit 739f8bd

Please sign in to comment.