Skip to content

Commit 739f8bd

Browse files
committed
Parse tag directives
1 parent 09595a3 commit 739f8bd

3 files changed

Lines changed: 37 additions & 8 deletions

File tree

examples/include_file_tag.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ impl<'a> IncludeParser<'a> {
2424
impl<'a> yaml::YamlScalarParser for IncludeParser<'a> {
2525
fn parse_scalar(&self, tag: &scanner::TokenType, value: &str) -> Option<yaml::Yaml> {
2626
if let scanner::TokenType::Tag(ref handle, ref suffix) = *tag {
27-
if *handle == "!" && *suffix == "include" {
27+
if (*handle == "!" || *handle == "yaml-rust.include.prefix") && *suffix == "include" {
2828
let mut content = String::new();
2929
return Some(match File::open(self.root.join(value)){
3030
Ok(mut f) => {

src/parser.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub struct Parser<T> {
7272
token: Option<Token>,
7373
anchors: HashMap<String, usize>,
7474
anchor_id: usize,
75+
tag_directives: HashMap<String, String>
7576
}
7677

7778

@@ -104,6 +105,7 @@ impl<T: Iterator<Item=char>> Parser<T> {
104105
anchors: HashMap::new(),
105106
// valid anchor_id starts from 1
106107
anchor_id: 1,
108+
tag_directives: HashMap::new()
107109
}
108110
}
109111

@@ -344,14 +346,14 @@ impl<T: Iterator<Item=char>> Parser<T> {
344346
// "found incompatible YAML document"));
345347
//}
346348
},
347-
TokenType::TagDirective(..) => {
348-
// TODO add tag directive
349+
TokenType::TagDirective(handle, mut prefix) => {
350+
prefix.pop(); //Remove :
351+
self.tag_directives.insert(handle , prefix);
349352
},
350353
_ => break
351354
}
352355
self.skip();
353356
}
354-
// TODO tag directive
355357
Ok(())
356358
}
357359

@@ -455,7 +457,19 @@ impl<T: Iterator<Item=char>> Parser<T> {
455457
TokenType::Scalar(style, v) => {
456458
self.pop_state();
457459
self.skip();
458-
Ok((Event::Scalar(v, style, anchor_id, tag), tok.0))
460+
461+
Ok((if let Some(TokenType::Tag(handle, suffix)) = tag{
462+
let t = self.tag_directives.get(&handle);
463+
Event::Scalar(v, style, anchor_id, Some(
464+
if let Some(s) = t {
465+
TokenType::Tag((*s).clone() , suffix)
466+
} else {
467+
TokenType::Tag(handle , suffix)
468+
}
469+
))
470+
} else {
471+
Event::Scalar(v, style, anchor_id, tag)
472+
}, tok.0))
459473
},
460474
TokenType::FlowSequenceStart => {
461475
self.state = State::FlowSequenceFirstEntry;

src/yaml.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,7 @@ c: ~
696696
impl YamlScalarParser for HelloTagParser {
697697
fn parse_scalar(&self, tag: &TokenType, value: &str) -> Option<Yaml> {
698698
if let TokenType::Tag(ref handle, ref suffix) = *tag {
699-
if *handle == "!" && *suffix == "hello" {
699+
if (*handle == "!" || *handle == "yaml-rust.hello.prefix") && *suffix == "hello" {
700700
return Some(Yaml::String("Hello ".to_string() + value))
701701
}
702702
}
@@ -709,8 +709,23 @@ c: ~
709709
let parser = HelloTagParser;
710710
let mut loader = YamlLoader::new();
711711
loader.register_scalar_parser(&parser);
712-
let out = loader.parse_from_str("- !hello world").unwrap();
712+
let out = loader.parse_from_str("!hello world").unwrap();
713713
let doc = &out[0];
714-
assert_eq!(doc[0].as_str().unwrap() , "Hello world")
714+
assert_eq!(doc.as_str().unwrap() , "Hello world")
715+
}
716+
717+
#[test]
718+
fn test_tag_directive() {
719+
let parser = HelloTagParser;
720+
let mut loader = YamlLoader::new();
721+
loader.register_scalar_parser(&parser);
722+
let out = loader.parse_from_str(
723+
"%YAML 1.2
724+
%TAG ! yaml-rust.hello.prefix:
725+
---
726+
!hello world"
727+
).unwrap();
728+
let doc = &out[0];
729+
assert_eq!(doc.as_str().unwrap() , "Hello world")
715730
}
716731
}

0 commit comments

Comments
 (0)