use granit_parser::{Event, Marker, Parser, ScalarStyle, ScanError, Span};
fn run_parser_with_span(input: &str) -> Result<Vec<(Event<'_>, Span)>, ScanError> {
let mut str_events = vec![];
let mut str_error = None;
let mut iter_events = vec![];
let mut iter_error = None;
for x in Parser::new_from_str(input) {
match x {
Ok(event) => str_events.push(event),
Err(e) => {
str_error = Some(e);
break;
}
}
}
for x in Parser::new_from_iter(input.chars()) {
match x {
Ok(event) => iter_events.push(event),
Err(e) => {
iter_error = Some(e);
break;
}
}
}
assert_eq!(str_events, iter_events);
assert_eq!(str_error, iter_error);
if let Some(err) = str_error {
Err(err)
} else {
Ok(str_events)
}
}
fn run_parser(input: &str) -> Result<Vec<Event<'_>>, ScanError> {
Ok(run_parser_with_span(input)?
.into_iter()
.map(|x| x.0)
.collect())
}
#[test]
#[allow(clippy::too_many_lines)]
fn test_issue1() {
let reference = r"
- a:
- 42
";
let expected = [
Event::StreamStart,
Event::DocumentStart(false),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("a".into(), ScalarStyle::Plain, 0, None),
Event::SequenceStart(0, None),
Event::Scalar("42".into(), ScalarStyle::Plain, 0, None),
Event::SequenceEnd,
Event::MappingEnd,
Event::SequenceEnd,
Event::DocumentEnd,
Event::StreamEnd,
];
assert_eq!(run_parser(reference).unwrap(), expected);
assert_eq!(run_parser("[{a: [42]}]").unwrap(), expected);
assert_eq!(run_parser("[a: [42]]").unwrap(), expected);
assert_eq!(
run_parser("[a: [1, 2]]").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("a".into(), ScalarStyle::Plain, 0, None),
Event::SequenceStart(0, None),
Event::Scalar("1".into(), ScalarStyle::Plain, 0, None),
Event::Scalar("2".into(), ScalarStyle::Plain, 0, None),
Event::SequenceEnd,
Event::MappingEnd,
Event::SequenceEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
let expected_mapping = [
Event::StreamStart,
Event::DocumentStart(false),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("a".into(), ScalarStyle::Plain, 0, None),
Event::MappingStart(0, None),
Event::Scalar("b".into(), ScalarStyle::Plain, 0, None),
Event::Scalar("c".into(), ScalarStyle::Plain, 0, None),
Event::Scalar("d".into(), ScalarStyle::Plain, 0, None),
Event::Scalar("e".into(), ScalarStyle::Plain, 0, None),
Event::MappingEnd,
Event::MappingEnd,
Event::SequenceEnd,
Event::DocumentEnd,
Event::StreamEnd,
];
assert_eq!(run_parser("[a: {b: c, d: e}]").unwrap(), expected_mapping);
assert_eq!(
run_parser("[foo: [bar]]: baz").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::MappingStart(0, None),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("foo".into(), ScalarStyle::Plain, 0, None),
Event::SequenceStart(0, None),
Event::Scalar("bar".into(), ScalarStyle::Plain, 0, None),
Event::SequenceEnd,
Event::MappingEnd,
Event::SequenceEnd,
Event::Scalar("baz".into(), ScalarStyle::Plain, 0, None),
Event::MappingEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
assert_eq!(
run_parser("[:]").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("~".into(), ScalarStyle::Plain, 0, None),
Event::Scalar("~".into(), ScalarStyle::Plain, 0, None),
Event::MappingEnd,
Event::SequenceEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
assert_eq!(
run_parser("[: [:]]").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("~".into(), ScalarStyle::Plain, 0, None),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("~".into(), ScalarStyle::Plain, 0, None),
Event::Scalar("~".into(), ScalarStyle::Plain, 0, None),
Event::MappingEnd,
Event::SequenceEnd,
Event::MappingEnd,
Event::SequenceEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
assert_eq!(
run_parser("[a: [ [b:]]]").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("a".into(), ScalarStyle::Plain, 0, None),
Event::SequenceStart(0, None),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("b".into(), ScalarStyle::Plain, 0, None),
Event::Scalar("~".into(), ScalarStyle::Plain, 0, None),
Event::MappingEnd,
Event::SequenceEnd,
Event::SequenceEnd,
Event::MappingEnd,
Event::SequenceEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
assert!(run_parser("[:[:]]").is_err());
assert!(run_parser("[a:[42]]").is_err());
assert_eq!(
run_parser(r#"["a":[]]"#).unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("a".into(), ScalarStyle::DoubleQuoted, 0, None),
Event::SequenceStart(0, None),
Event::SequenceEnd,
Event::MappingEnd,
Event::SequenceEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
}
#[test]
fn test_flow_sequence_empty_key_with_value() {
assert_eq!(
run_parser("[: value]").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("~".into(), ScalarStyle::Plain, 0, None),
Event::Scalar("value".into(), ScalarStyle::Plain, 0, None),
Event::MappingEnd,
Event::SequenceEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
}
#[test]
fn test_flow_sequence_empty_key_state_is_flow_scoped() {
assert_eq!(
run_parser("[ : [foo] ]").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("~".into(), ScalarStyle::Plain, 0, None),
Event::SequenceStart(0, None),
Event::Scalar("foo".into(), ScalarStyle::Plain, 0, None),
Event::SequenceEnd,
Event::MappingEnd,
Event::SequenceEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
assert_eq!(
run_parser("[ : {a: b} ]").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("~".into(), ScalarStyle::Plain, 0, None),
Event::MappingStart(0, None),
Event::Scalar("a".into(), ScalarStyle::Plain, 0, None),
Event::Scalar("b".into(), ScalarStyle::Plain, 0, None),
Event::MappingEnd,
Event::MappingEnd,
Event::SequenceEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
assert_eq!(
run_parser("[{}, : foo]").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::MappingEnd,
Event::MappingStart(0, None),
Event::Scalar("~".into(), ScalarStyle::Plain, 0, None),
Event::Scalar("foo".into(), ScalarStyle::Plain, 0, None),
Event::MappingEnd,
Event::SequenceEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
}
#[test]
fn test_flow_mapping_quoted_key_colon_on_next_line() {
assert_eq!(
run_parser("{\"foo\"\n: \"bar\"}\n").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::MappingStart(0, None),
Event::Scalar("foo".into(), ScalarStyle::DoubleQuoted, 0, None),
Event::Scalar("bar".into(), ScalarStyle::DoubleQuoted, 0, None),
Event::MappingEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
}
#[test]
fn test_flow_mapping_plain_key_spans_line_break() {
assert_eq!(
run_parser("- { single line: value}\n- { multi\n line: value}\n").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("single line".into(), ScalarStyle::Plain, 0, None),
Event::Scalar("value".into(), ScalarStyle::Plain, 0, None),
Event::MappingEnd,
Event::MappingStart(0, None),
Event::Scalar("multi line".into(), ScalarStyle::Plain, 0, None),
Event::Scalar("value".into(), ScalarStyle::Plain, 0, None),
Event::MappingEnd,
Event::SequenceEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
}
#[test]
fn test_flow_mapping_key_and_colon_on_separate_lines() {
assert_eq!(
run_parser("k: {\n k\n :\n v\n }\n").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::MappingStart(0, None),
Event::Scalar("k".into(), ScalarStyle::Plain, 0, None),
Event::MappingStart(0, None),
Event::Scalar("k".into(), ScalarStyle::Plain, 0, None),
Event::Scalar("v".into(), ScalarStyle::Plain, 0, None),
Event::MappingEnd,
Event::MappingEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
}
#[test]
fn test_pr12() {
assert_eq!(
run_parser("---\n- |\n a").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(true),
Event::SequenceStart(0, None),
Event::Scalar("a\n".into(), ScalarStyle::Literal, 0, None),
Event::SequenceEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
}
#[test]
fn test_issue14() {
let s = "{---";
let Err(error) = run_parser(s) else { panic!() };
assert_eq!(error.info(), "unclosed bracket '{'");
assert_eq!(error.marker().index(), 0);
}
#[test]
fn test_issue14_v2() {
let s = "{...";
let Err(error) = run_parser(s) else { panic!() };
assert_eq!(error.info(), "unclosed bracket '{'");
assert_eq!(error.marker().index(), 0);
}
#[test]
fn test_issue13() {
let s = r"---
array:
- object:
array:
- object:
array:
- text: >-
Line 1
Line 2
...";
assert_eq!(
run_parser(s).unwrap(),
[
Event::StreamStart,
Event::DocumentStart(true),
Event::MappingStart(0, None),
Event::Scalar("array".into(), ScalarStyle::Plain, 0, None),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("object".into(), ScalarStyle::Plain, 0, None),
Event::MappingStart(0, None),
Event::Scalar("array".into(), ScalarStyle::Plain, 0, None),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("object".into(), ScalarStyle::Plain, 0, None),
Event::MappingStart(0, None),
Event::Scalar("array".into(), ScalarStyle::Plain, 0, None),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("text".into(), ScalarStyle::Plain, 0, None),
Event::Scalar("Line 1 Line 2".into(), ScalarStyle::Folded, 0, None),
Event::MappingEnd,
Event::SequenceEnd,
Event::MappingEnd,
Event::MappingEnd,
Event::SequenceEnd,
Event::MappingEnd,
Event::MappingEnd,
Event::SequenceEnd,
Event::MappingEnd,
Event::DocumentEnd,
Event::StreamEnd
]
);
}
#[test]
fn test_issue22() {
let s = "comment: hello ... world";
assert_eq!(
run_parser(s).unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::MappingStart(0, None),
Event::Scalar("comment".into(), ScalarStyle::Plain, 0, None),
Event::Scalar("hello ... world".into(), ScalarStyle::Plain, 0, None),
Event::MappingEnd,
Event::DocumentEnd,
Event::StreamEnd
]
);
}
#[test]
#[rustfmt::skip]
fn test_issue37() {
let s = r"---
hash_block_null_value:
hash_flow: {hash_flow_null_value: null}
array_block_null_value:
-
- ~
- null
array_flow_null_value: [~, null]
indentless_array_block_null_value:
-
- ~
- null
";
assert_eq!(
run_parser_with_span(s).unwrap(),
[
(Event::StreamStart, Span::new(Marker::new(0, 1, 0).with_byte_offset(Some(0)), Marker::new(0, 1, 0).with_byte_offset(Some(0)))),
(Event::DocumentStart(true), Span::new(Marker::new(0, 1, 0).with_byte_offset(Some(0)), Marker::new(3, 1, 3).with_byte_offset(Some(3)))),
(Event::MappingStart(0, None), Span::new(Marker::new(8, 2, 4).with_byte_offset(Some(8)), Marker::new(8, 2, 4).with_byte_offset(Some(8)))),
(Event::Scalar("hash_block_null_value".into(), ScalarStyle::Plain, 0, None), Span::new(Marker::new(8, 2, 4).with_byte_offset(Some(8)), Marker::new(29, 2, 25).with_byte_offset(Some(29))).with_indent(Some(4))),
(Event::Scalar("~".into(), ScalarStyle::Plain, 0, None), Span::new(Marker::new(29, 2, 25).with_byte_offset(Some(29)), Marker::new(29, 2, 25).with_byte_offset(Some(29)))),
(Event::Scalar("hash_flow".into(), ScalarStyle::Plain, 0, None), Span::new(Marker::new(35, 3, 4).with_byte_offset(Some(35)), Marker::new(44, 3, 13).with_byte_offset(Some(44))).with_indent(Some(4))),
(Event::MappingStart(0, None), Span::new(Marker::new(46, 3, 15).with_byte_offset(Some(46)), Marker::new(47, 3, 16).with_byte_offset(Some(47)))),
(Event::Scalar("hash_flow_null_value".into(), ScalarStyle::Plain, 0, None), Span::new(Marker::new(47, 3, 16).with_byte_offset(Some(47)), Marker::new(67, 3, 36).with_byte_offset(Some(67)))),
(Event::Scalar("null".into(), ScalarStyle::Plain, 0, None), Span::new(Marker::new(69, 3, 38).with_byte_offset(Some(69)), Marker::new(73, 3, 42).with_byte_offset(Some(73)))),
(Event::MappingEnd, Span::new(Marker::new(73, 3, 42).with_byte_offset(Some(73)), Marker::new(74, 3, 43).with_byte_offset(Some(74)))),
(Event::Scalar("array_block_null_value".into(), ScalarStyle::Plain, 0, None), Span::new(Marker::new(79, 4, 4).with_byte_offset(Some(79)), Marker::new(101, 4, 26).with_byte_offset(Some(101))).with_indent(Some(4))),
(Event::SequenceStart(0, None), Span::new(Marker::new(109, 5, 6).with_byte_offset(Some(109)), Marker::new(109, 5, 6).with_byte_offset(Some(109)))),
(Event::Scalar("~".into(), ScalarStyle::Plain, 0, None), Span::new(Marker::new(110, 5, 7).with_byte_offset(Some(110)), Marker::new(110, 5, 7).with_byte_offset(Some(110)))),
(Event::Scalar("~".into(), ScalarStyle::Plain, 0, None), Span::new(Marker::new(119, 6, 8).with_byte_offset(Some(119)), Marker::new(120, 6, 9).with_byte_offset(Some(120)))),
(Event::Scalar("null".into(), ScalarStyle::Plain, 0, None), Span::new(Marker::new(129, 7, 8).with_byte_offset(Some(129)), Marker::new(133, 7, 12).with_byte_offset(Some(133)))),
(Event::SequenceEnd, Span::new(Marker::new(138, 8, 4).with_byte_offset(Some(138)), Marker::new(138, 8, 4).with_byte_offset(Some(138)))),
(Event::Scalar("array_flow_null_value".into(), ScalarStyle::Plain, 0, None), Span::new(Marker::new(138, 8, 4).with_byte_offset(Some(138)), Marker::new(159, 8, 25).with_byte_offset(Some(159))).with_indent(Some(4))),
(Event::SequenceStart(0, None), Span::new(Marker::new(161, 8, 27).with_byte_offset(Some(161)), Marker::new(162, 8, 28).with_byte_offset(Some(162)))),
(Event::Scalar("~".into(), ScalarStyle::Plain, 0, None), Span::new(Marker::new(162, 8, 28).with_byte_offset(Some(162)), Marker::new(163, 8, 29).with_byte_offset(Some(163)))),
(Event::Scalar("null".into(), ScalarStyle::Plain, 0, None), Span::new(Marker::new(165, 8, 31).with_byte_offset(Some(165)), Marker::new(169, 8, 35).with_byte_offset(Some(169)))),
(Event::SequenceEnd, Span::new(Marker::new(169, 8, 35).with_byte_offset(Some(169)), Marker::new(170, 8, 36).with_byte_offset(Some(170)))),
(Event::Scalar("indentless_array_block_null_value".into(), ScalarStyle::Plain, 0, None), Span::new(Marker::new(175, 9, 4).with_byte_offset(Some(175)), Marker::new(208, 9, 37).with_byte_offset(Some(208))).with_indent(Some(4))),
(Event::SequenceStart(0, None), Span::new(Marker::new(215, 10, 5).with_byte_offset(Some(215)), Marker::new(215, 10, 5).with_byte_offset(Some(215)))),
(Event::Scalar("~".into(), ScalarStyle::Plain, 0, None), Span::new(Marker::new(215, 10, 5).with_byte_offset(Some(215)), Marker::new(215, 10, 5).with_byte_offset(Some(215)))),
(Event::Scalar("~".into(), ScalarStyle::Plain, 0, None), Span::new(Marker::new(222, 11, 6).with_byte_offset(Some(222)), Marker::new(223, 11, 7).with_byte_offset(Some(223)))),
(Event::Scalar("null".into(), ScalarStyle::Plain, 0, None), Span::new(Marker::new(230, 12, 6).with_byte_offset(Some(230)), Marker::new(234, 12, 10).with_byte_offset(Some(234)))),
(Event::SequenceEnd, Span::new(Marker::new(239, 14, 0).with_byte_offset(Some(239)), Marker::new(239, 14, 0).with_byte_offset(Some(239)))),
(Event::MappingEnd, Span::new(Marker::new(239, 14, 0).with_byte_offset(Some(239)), Marker::new(239, 14, 0).with_byte_offset(Some(239)))),
(Event::DocumentEnd, Span::new(Marker::new(239, 14, 0).with_byte_offset(Some(239)), Marker::new(239, 14, 0).with_byte_offset(Some(239)))),
(Event::StreamEnd, Span::new(Marker::new(239, 14, 0).with_byte_offset(Some(239)), Marker::new(239, 14, 0).with_byte_offset(Some(239))))
]
);
}
#[test]
fn test_issue84() {
let s = r"hello:
world: this is a string
--- still a string";
assert_eq!(
run_parser(s).unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::MappingStart(0, None),
Event::Scalar("hello".into(), ScalarStyle::Plain, 0, None),
Event::MappingStart(0, None),
Event::Scalar("world".into(), ScalarStyle::Plain, 0, None),
Event::Scalar(
"this is a string --- still a string".into(),
ScalarStyle::Plain,
0,
None
),
Event::MappingEnd,
Event::MappingEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
}