parser: add an option to keep tags across multiple documents
Documents are self-contained and tags defined in the first document are not visible to subsequent documents. Add support for having tags that span across all documents by making the clearing of tags in the parser opt-out. Closes: #10
This commit is contained in:
parent
16f3ea39e1
commit
150b6f0927
1 changed files with 34 additions and 1 deletions
|
@ -115,6 +115,8 @@ pub struct Parser<T> {
|
|||
///
|
||||
/// Key is the handle, and value is the prefix.
|
||||
tags: HashMap<String, String>,
|
||||
/// Make tags global across all documents.
|
||||
keep_tags: bool,
|
||||
}
|
||||
|
||||
/// Trait to be implemented in order to use the low-level parsing API.
|
||||
|
@ -222,9 +224,17 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
// valid anchor_id starts from 1
|
||||
anchor_id: 1,
|
||||
tags: HashMap::new(),
|
||||
keep_tags: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Make tags persistent when parsing multiple documents.
|
||||
#[must_use]
|
||||
pub fn keep_tags(mut self, value: bool) -> Self {
|
||||
self.keep_tags = value;
|
||||
self
|
||||
}
|
||||
|
||||
/// Try to load the next event and return it, but do not consuming it from `self`.
|
||||
///
|
||||
/// Any subsequent call to [`Parser::peek`] will return the same value, until a call to
|
||||
|
@ -595,7 +605,9 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
Token(mark, _) => mark,
|
||||
};
|
||||
|
||||
self.tags.clear();
|
||||
if !self.keep_tags {
|
||||
self.tags.clear();
|
||||
}
|
||||
if explicit_end {
|
||||
self.state = State::ImplicitDocumentStart;
|
||||
} else {
|
||||
|
@ -1050,6 +1062,7 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{Event, Parser};
|
||||
use crate::YamlLoader;
|
||||
|
||||
#[test]
|
||||
fn test_peek_eq_parse() {
|
||||
|
@ -1073,4 +1086,24 @@ a5: *x
|
|||
event.0 != Event::StreamEnd
|
||||
} {}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_keep_tags_across_multiple_documents() {
|
||||
let text = r#"
|
||||
%YAML 1.1
|
||||
%TAG !t! tag:test,2024:
|
||||
--- !t!1 &1
|
||||
foo: "bar"
|
||||
--- !t!2 &2
|
||||
baz: "qux"
|
||||
"#;
|
||||
let mut loader = YamlLoader::default();
|
||||
let mut parser = Parser::new(text.chars()).keep_tags(true);
|
||||
assert!(parser.load(&mut loader, true).is_ok());
|
||||
assert_eq!(loader.documents().len(), 2);
|
||||
let yaml = &loader.documents()[0];
|
||||
assert_eq!(yaml["foo"].as_str(), Some("bar"));
|
||||
let yaml = &loader.documents()[1];
|
||||
assert_eq!(yaml["baz"].as_str(), Some("qux"));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue