Clippy set to pedantic.
This commit is contained in:
parent
b6e65fb359
commit
fd37ebd6e5
8 changed files with 273 additions and 269 deletions
|
@ -21,13 +21,13 @@ fn dump_node(doc: &yaml::Yaml, indent: usize) {
|
|||
yaml::Yaml::Hash(ref h) => {
|
||||
for (k, v) in h {
|
||||
print_indent(indent);
|
||||
println!("{:?}:", k);
|
||||
println!("{k:?}:");
|
||||
dump_node(v, indent + 1);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
print_indent(indent);
|
||||
println!("{:?}", doc);
|
||||
println!("{doc:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::yaml::{Hash, Yaml};
|
||||
use std::convert::From;
|
||||
use std::error::Error;
|
||||
use std::fmt::{self, Display};
|
||||
use crate::yaml::{Hash, Yaml};
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum EmitError {
|
||||
|
@ -30,6 +30,7 @@ impl From<fmt::Error> for EmitError {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::module_name_repetitions)]
|
||||
pub struct YamlEmitter<'a> {
|
||||
writer: &'a mut dyn fmt::Write,
|
||||
best_indent: usize,
|
||||
|
@ -126,6 +127,7 @@ impl<'a> YamlEmitter<'a> {
|
|||
}
|
||||
|
||||
/// Determine if this emitter is using 'compact inline notation'.
|
||||
#[must_use]
|
||||
pub fn is_compact(&self) -> bool {
|
||||
self.compact
|
||||
}
|
||||
|
@ -157,7 +159,7 @@ impl<'a> YamlEmitter<'a> {
|
|||
if need_quotes(v) {
|
||||
escape_str(self.writer, v)?;
|
||||
} else {
|
||||
write!(self.writer, "{}", v)?;
|
||||
write!(self.writer, "{v}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -170,11 +172,11 @@ impl<'a> YamlEmitter<'a> {
|
|||
Ok(())
|
||||
}
|
||||
Yaml::Integer(v) => {
|
||||
write!(self.writer, "{}", v)?;
|
||||
write!(self.writer, "{v}")?;
|
||||
Ok(())
|
||||
}
|
||||
Yaml::Real(ref v) => {
|
||||
write!(self.writer, "{}", v)?;
|
||||
write!(self.writer, "{v}")?;
|
||||
Ok(())
|
||||
}
|
||||
Yaml::Null | Yaml::BadValue => {
|
||||
|
@ -182,7 +184,7 @@ impl<'a> YamlEmitter<'a> {
|
|||
Ok(())
|
||||
}
|
||||
// XXX(chenyh) Alias
|
||||
_ => Ok(()),
|
||||
Yaml::Alias(_) => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -210,10 +212,7 @@ impl<'a> YamlEmitter<'a> {
|
|||
} else {
|
||||
self.level += 1;
|
||||
for (cnt, (k, v)) in h.iter().enumerate() {
|
||||
let complex_key = match *k {
|
||||
Yaml::Hash(_) | Yaml::Array(_) => true,
|
||||
_ => false,
|
||||
};
|
||||
let complex_key = matches!(*k, Yaml::Hash(_) | Yaml::Array(_));
|
||||
if cnt > 0 {
|
||||
writeln!(self.writer)?;
|
||||
self.write_indent()?;
|
||||
|
@ -286,19 +285,22 @@ impl<'a> YamlEmitter<'a> {
|
|||
/// * When the string is null or ~ (otherwise, it would be considered as a null value);
|
||||
/// * When the string looks like a number, such as integers (e.g. 2, 14, etc.), floats (e.g. 2.6, 14.9) and exponential numbers (e.g. 12e7, etc.) (otherwise, it would be treated as a numeric value);
|
||||
/// * When the string looks like a date (e.g. 2014-12-31) (otherwise it would be automatically converted into a Unix timestamp).
|
||||
#[allow(clippy::doc_markdown)]
|
||||
fn need_quotes(string: &str) -> bool {
|
||||
fn need_quotes_spaces(string: &str) -> bool {
|
||||
string.starts_with(' ') || string.ends_with(' ')
|
||||
}
|
||||
|
||||
string == ""
|
||||
string.is_empty()
|
||||
|| need_quotes_spaces(string)
|
||||
|| string.starts_with(|character: char| match character {
|
||||
'&' | '*' | '?' | '|' | '-' | '<' | '>' | '=' | '!' | '%' | '@' => true,
|
||||
_ => false,
|
||||
|| string.starts_with(|character: char| {
|
||||
matches!(
|
||||
character,
|
||||
'&' | '*' | '?' | '|' | '-' | '<' | '>' | '=' | '!' | '%' | '@'
|
||||
)
|
||||
})
|
||||
|| string.contains(|character: char| match character {
|
||||
':'
|
||||
|| string.contains(|character: char| {
|
||||
matches!(character, ':'
|
||||
| '{'
|
||||
| '}'
|
||||
| '['
|
||||
|
@ -314,8 +316,7 @@ fn need_quotes(string: &str) -> bool {
|
|||
| '\n'
|
||||
| '\r'
|
||||
| '\x0e'..='\x1a'
|
||||
| '\x1c'..='\x1f' => true,
|
||||
_ => false,
|
||||
| '\x1c'..='\x1f')
|
||||
})
|
||||
|| [
|
||||
// http://yaml.org/type/bool.html
|
||||
|
@ -335,6 +336,7 @@ fn need_quotes(string: &str) -> bool {
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(clippy::similar_names)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::YamlLoader;
|
||||
|
@ -354,18 +356,18 @@ a4:
|
|||
- 2
|
||||
";
|
||||
|
||||
let docs = YamlLoader::load_from_str(&s).unwrap();
|
||||
let docs = YamlLoader::load_from_str(s).unwrap();
|
||||
let doc = &docs[0];
|
||||
let mut writer = String::new();
|
||||
{
|
||||
let mut emitter = YamlEmitter::new(&mut writer);
|
||||
emitter.dump(doc).unwrap();
|
||||
}
|
||||
println!("original:\n{}", s);
|
||||
println!("emitted:\n{}", writer);
|
||||
println!("original:\n{s}");
|
||||
println!("emitted:\n{writer}");
|
||||
let docs_new = match YamlLoader::load_from_str(&writer) {
|
||||
Ok(y) => y,
|
||||
Err(e) => panic!(format!("{}", e)),
|
||||
Err(e) => panic!("{}", e),
|
||||
};
|
||||
let doc_new = &docs_new[0];
|
||||
|
||||
|
@ -393,7 +395,7 @@ products:
|
|||
{}:
|
||||
empty hash key
|
||||
"#;
|
||||
let docs = YamlLoader::load_from_str(&s).unwrap();
|
||||
let docs = YamlLoader::load_from_str(s).unwrap();
|
||||
let doc = &docs[0];
|
||||
let mut writer = String::new();
|
||||
{
|
||||
|
@ -402,7 +404,7 @@ products:
|
|||
}
|
||||
let docs_new = match YamlLoader::load_from_str(&writer) {
|
||||
Ok(y) => y,
|
||||
Err(e) => panic!(format!("{}", e)),
|
||||
Err(e) => panic!("{}", e),
|
||||
};
|
||||
let doc_new = &docs_new[0];
|
||||
assert_eq!(doc, doc_new);
|
||||
|
@ -444,7 +446,7 @@ x: test
|
|||
y: avoid quoting here
|
||||
z: string with spaces"#;
|
||||
|
||||
let docs = YamlLoader::load_from_str(&s).unwrap();
|
||||
let docs = YamlLoader::load_from_str(s).unwrap();
|
||||
let doc = &docs[0];
|
||||
let mut writer = String::new();
|
||||
{
|
||||
|
@ -452,7 +454,7 @@ z: string with spaces"#;
|
|||
emitter.dump(doc).unwrap();
|
||||
}
|
||||
|
||||
assert_eq!(s, writer, "actual:\n\n{}\n", writer);
|
||||
assert_eq!(s, writer, "actual:\n\n{writer}\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -502,7 +504,7 @@ null0: ~
|
|||
bool0: true
|
||||
bool1: false"#;
|
||||
|
||||
let docs = YamlLoader::load_from_str(&input).unwrap();
|
||||
let docs = YamlLoader::load_from_str(input).unwrap();
|
||||
let doc = &docs[0];
|
||||
let mut writer = String::new();
|
||||
{
|
||||
|
@ -512,19 +514,18 @@ bool1: false"#;
|
|||
|
||||
assert_eq!(
|
||||
expected, writer,
|
||||
"expected:\n{}\nactual:\n{}\n",
|
||||
expected, writer
|
||||
"expected:\n{expected}\nactual:\n{writer}\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_and_nested() {
|
||||
test_empty_and_nested_flag(false)
|
||||
test_empty_and_nested_flag(false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_and_nested_compact() {
|
||||
test_empty_and_nested_flag(true)
|
||||
test_empty_and_nested_flag(true);
|
||||
}
|
||||
|
||||
fn test_empty_and_nested_flag(compact: bool) {
|
||||
|
@ -551,7 +552,7 @@ e:
|
|||
h: []"#
|
||||
};
|
||||
|
||||
let docs = YamlLoader::load_from_str(&s).unwrap();
|
||||
let docs = YamlLoader::load_from_str(s).unwrap();
|
||||
let doc = &docs[0];
|
||||
let mut writer = String::new();
|
||||
{
|
||||
|
@ -573,15 +574,15 @@ a:
|
|||
- - e
|
||||
- f"#;
|
||||
|
||||
let docs = YamlLoader::load_from_str(&s).unwrap();
|
||||
let docs = YamlLoader::load_from_str(s).unwrap();
|
||||
let doc = &docs[0];
|
||||
let mut writer = String::new();
|
||||
{
|
||||
let mut emitter = YamlEmitter::new(&mut writer);
|
||||
emitter.dump(doc).unwrap();
|
||||
}
|
||||
println!("original:\n{}", s);
|
||||
println!("emitted:\n{}", writer);
|
||||
println!("original:\n{s}");
|
||||
println!("emitted:\n{writer}");
|
||||
|
||||
assert_eq!(s, writer);
|
||||
}
|
||||
|
@ -597,15 +598,15 @@ a:
|
|||
- - f
|
||||
- - e"#;
|
||||
|
||||
let docs = YamlLoader::load_from_str(&s).unwrap();
|
||||
let docs = YamlLoader::load_from_str(s).unwrap();
|
||||
let doc = &docs[0];
|
||||
let mut writer = String::new();
|
||||
{
|
||||
let mut emitter = YamlEmitter::new(&mut writer);
|
||||
emitter.dump(doc).unwrap();
|
||||
}
|
||||
println!("original:\n{}", s);
|
||||
println!("emitted:\n{}", writer);
|
||||
println!("original:\n{s}");
|
||||
println!("emitted:\n{writer}");
|
||||
|
||||
assert_eq!(s, writer);
|
||||
}
|
||||
|
@ -619,17 +620,16 @@ a:
|
|||
d:
|
||||
e: f"#;
|
||||
|
||||
let docs = YamlLoader::load_from_str(&s).unwrap();
|
||||
let docs = YamlLoader::load_from_str(s).unwrap();
|
||||
let doc = &docs[0];
|
||||
let mut writer = String::new();
|
||||
{
|
||||
let mut emitter = YamlEmitter::new(&mut writer);
|
||||
emitter.dump(doc).unwrap();
|
||||
}
|
||||
println!("original:\n{}", s);
|
||||
println!("emitted:\n{}", writer);
|
||||
println!("original:\n{s}");
|
||||
println!("emitted:\n{writer}");
|
||||
|
||||
assert_eq!(s, writer);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -37,11 +37,16 @@
|
|||
//! ```
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/yaml-rust/0.4.5")]
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(feature = "cargo-clippy", warn(cyclomatic_complexity))]
|
||||
#![cfg_attr(feature = "cargo-clippy", warn(clippy::pedantic))]
|
||||
#![cfg_attr(
|
||||
feature = "cargo-clippy",
|
||||
allow(match_same_arms, should_implement_trait)
|
||||
allow(
|
||||
clippy::match_same_arms,
|
||||
clippy::should_implement_trait,
|
||||
clippy::missing_errors_doc,
|
||||
clippy::missing_panics_doc,
|
||||
clippy::redundant_else,
|
||||
)
|
||||
)]
|
||||
|
||||
extern crate linked_hash_map;
|
||||
|
@ -117,5 +122,4 @@ key1:a2
|
|||
assert!(YamlLoader::load_from_str(s).is_err());
|
||||
assert!(try_fail(s).is_err());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::scanner::*;
|
||||
use crate::scanner::{Marker, ScanError, Scanner, TScalarStyle, Token, TokenType};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Debug, Eq)]
|
||||
|
@ -58,11 +58,12 @@ impl Event {
|
|||
}
|
||||
|
||||
fn empty_scalar_with_anchor(anchor: usize, tag: Option<TokenType>) -> Event {
|
||||
Event::Scalar("".to_owned(), TScalarStyle::Plain, anchor, tag)
|
||||
Event::Scalar(String::new(), TScalarStyle::Plain, anchor, tag)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub struct Parser<T> {
|
||||
scanner: Scanner<T>,
|
||||
states: Vec<State>,
|
||||
|
@ -84,7 +85,7 @@ pub trait MarkedEventReceiver {
|
|||
|
||||
impl<R: EventReceiver> MarkedEventReceiver for R {
|
||||
fn on_event(&mut self, ev: Event, _mark: Marker) {
|
||||
self.on_event(ev)
|
||||
self.on_event(ev);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,12 +108,11 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
}
|
||||
|
||||
pub fn peek(&mut self) -> Result<&(Event, Marker), ScanError> {
|
||||
match self.current {
|
||||
Some(ref x) => Ok(x),
|
||||
None => {
|
||||
self.current = Some(self.next()?);
|
||||
self.peek()
|
||||
}
|
||||
if let Some(ref x) = self.current {
|
||||
Ok(x)
|
||||
} else {
|
||||
self.current = Some(self.next()?);
|
||||
self.peek()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
//self.peek_token();
|
||||
}
|
||||
fn pop_state(&mut self) {
|
||||
self.state = self.states.pop().unwrap()
|
||||
self.state = self.states.pop().unwrap();
|
||||
}
|
||||
fn push_state(&mut self, state: State) {
|
||||
self.states.push(state);
|
||||
|
@ -242,7 +242,7 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
self.load_mapping(recv)
|
||||
}
|
||||
_ => {
|
||||
println!("UNREACHABLE EVENT: {:?}", first_ev);
|
||||
println!("UNREACHABLE EVENT: {first_ev:?}");
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
@ -345,9 +345,12 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
self.skip();
|
||||
Ok((Event::StreamEnd, mark))
|
||||
}
|
||||
Token(_, TokenType::VersionDirective(..))
|
||||
| Token(_, TokenType::TagDirective(..))
|
||||
| Token(_, TokenType::DocumentStart) => {
|
||||
Token(
|
||||
_,
|
||||
TokenType::VersionDirective(..)
|
||||
| TokenType::TagDirective(..)
|
||||
| TokenType::DocumentStart,
|
||||
) => {
|
||||
// explicit document
|
||||
self._explicit_document_start()
|
||||
}
|
||||
|
@ -403,11 +406,14 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
|
||||
fn document_content(&mut self) -> ParseResult {
|
||||
match *self.peek_token()? {
|
||||
Token(mark, TokenType::VersionDirective(..))
|
||||
| Token(mark, TokenType::TagDirective(..))
|
||||
| Token(mark, TokenType::DocumentStart)
|
||||
| Token(mark, TokenType::DocumentEnd)
|
||||
| Token(mark, TokenType::StreamEnd) => {
|
||||
Token(
|
||||
mark,
|
||||
TokenType::VersionDirective(..)
|
||||
| TokenType::TagDirective(..)
|
||||
| TokenType::DocumentStart
|
||||
| TokenType::DocumentEnd
|
||||
| TokenType::StreamEnd,
|
||||
) => {
|
||||
self.pop_state();
|
||||
// empty scalar
|
||||
Ok((Event::empty_scalar(), mark))
|
||||
|
@ -417,11 +423,9 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
}
|
||||
|
||||
fn document_end(&mut self) -> ParseResult {
|
||||
let mut _implicit = true;
|
||||
let marker: Marker = match *self.peek_token()? {
|
||||
Token(mark, TokenType::DocumentEnd) => {
|
||||
self.skip();
|
||||
_implicit = false;
|
||||
mark
|
||||
}
|
||||
Token(mark, _) => mark,
|
||||
|
@ -432,7 +436,7 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
Ok((Event::DocumentEnd, marker))
|
||||
}
|
||||
|
||||
fn register_anchor(&mut self, name: String, _: &Marker) -> Result<usize, ScanError> {
|
||||
fn register_anchor(&mut self, name: String, _: &Marker) -> usize {
|
||||
// anchors can be overridden/reused
|
||||
// if self.anchors.contains_key(name) {
|
||||
// return Err(ScanError::new(*mark,
|
||||
|
@ -441,7 +445,7 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
let new_id = self.anchor_id;
|
||||
self.anchor_id += 1;
|
||||
self.anchors.insert(name, new_id);
|
||||
Ok(new_id)
|
||||
new_id
|
||||
}
|
||||
|
||||
fn parse_node(&mut self, block: bool, indentless_sequence: bool) -> ParseResult {
|
||||
|
@ -466,7 +470,7 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
}
|
||||
Token(_, TokenType::Anchor(_)) => {
|
||||
if let Token(mark, TokenType::Anchor(name)) = self.fetch_token() {
|
||||
anchor_id = self.register_anchor(name, &mark)?;
|
||||
anchor_id = self.register_anchor(name, &mark);
|
||||
if let TokenType::Tag(..) = self.peek_token()?.1 {
|
||||
if let tg @ TokenType::Tag(..) = self.fetch_token().1 {
|
||||
tag = Some(tg);
|
||||
|
@ -483,7 +487,7 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
tag = Some(tg);
|
||||
if let TokenType::Anchor(_) = self.peek_token()?.1 {
|
||||
if let Token(mark, TokenType::Anchor(name)) = self.fetch_token() {
|
||||
anchor_id = self.register_anchor(name, &mark)?;
|
||||
anchor_id = self.register_anchor(name, &mark);
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
|
@ -545,18 +549,15 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
match *self.peek_token()? {
|
||||
Token(_, TokenType::Key) => {
|
||||
self.skip();
|
||||
match *self.peek_token()? {
|
||||
Token(mark, TokenType::Key)
|
||||
| Token(mark, TokenType::Value)
|
||||
| Token(mark, TokenType::BlockEnd) => {
|
||||
self.state = State::BlockMappingValue;
|
||||
// empty scalar
|
||||
Ok((Event::empty_scalar(), mark))
|
||||
}
|
||||
_ => {
|
||||
self.push_state(State::BlockMappingValue);
|
||||
self.parse_node(true, true)
|
||||
}
|
||||
if let Token(mark, TokenType::Key | TokenType::Value | TokenType::BlockEnd) =
|
||||
*self.peek_token()?
|
||||
{
|
||||
self.state = State::BlockMappingValue;
|
||||
// empty scalar
|
||||
Ok((Event::empty_scalar(), mark))
|
||||
} else {
|
||||
self.push_state(State::BlockMappingValue);
|
||||
self.parse_node(true, true)
|
||||
}
|
||||
}
|
||||
// XXX(chenyh): libyaml failed to parse spec 1.2, ex8.18
|
||||
|
@ -580,18 +581,15 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
match *self.peek_token()? {
|
||||
Token(_, TokenType::Value) => {
|
||||
self.skip();
|
||||
match *self.peek_token()? {
|
||||
Token(mark, TokenType::Key)
|
||||
| Token(mark, TokenType::Value)
|
||||
| Token(mark, TokenType::BlockEnd) => {
|
||||
self.state = State::BlockMappingKey;
|
||||
// empty scalar
|
||||
Ok((Event::empty_scalar(), mark))
|
||||
}
|
||||
_ => {
|
||||
self.push_state(State::BlockMappingKey);
|
||||
self.parse_node(true, true)
|
||||
}
|
||||
if let Token(mark, TokenType::Key | TokenType::Value | TokenType::BlockEnd) =
|
||||
*self.peek_token()?
|
||||
{
|
||||
self.state = State::BlockMappingKey;
|
||||
// empty scalar
|
||||
Ok((Event::empty_scalar(), mark))
|
||||
} else {
|
||||
self.push_state(State::BlockMappingKey);
|
||||
self.parse_node(true, true)
|
||||
}
|
||||
}
|
||||
Token(mark, _) => {
|
||||
|
@ -607,50 +605,50 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
let _ = self.peek_token()?;
|
||||
self.skip();
|
||||
}
|
||||
let marker: Marker =
|
||||
{
|
||||
match *self.peek_token()? {
|
||||
Token(mark, TokenType::FlowMappingEnd) => mark,
|
||||
Token(mark, _) => {
|
||||
if !first {
|
||||
match *self.peek_token()? {
|
||||
Token(_, TokenType::FlowEntry) => self.skip(),
|
||||
Token(mark, _) => return Err(ScanError::new(mark,
|
||||
"while parsing a flow mapping, did not find expected ',' or '}'"))
|
||||
}
|
||||
}
|
||||
|
||||
let marker: Marker = {
|
||||
match *self.peek_token()? {
|
||||
Token(mark, TokenType::FlowMappingEnd) => mark,
|
||||
Token(mark, _) => {
|
||||
if !first {
|
||||
match *self.peek_token()? {
|
||||
Token(_, TokenType::Key) => {
|
||||
self.skip();
|
||||
match *self.peek_token()? {
|
||||
Token(mark, TokenType::Value)
|
||||
| Token(mark, TokenType::FlowEntry)
|
||||
| Token(mark, TokenType::FlowMappingEnd) => {
|
||||
self.state = State::FlowMappingValue;
|
||||
return Ok((Event::empty_scalar(), mark));
|
||||
}
|
||||
_ => {
|
||||
self.push_state(State::FlowMappingValue);
|
||||
return self.parse_node(false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
Token(marker, TokenType::Value) => {
|
||||
Token(_, TokenType::FlowEntry) => self.skip(),
|
||||
Token(mark, _) => return Err(ScanError::new(
|
||||
mark,
|
||||
"while parsing a flow mapping, did not find expected ',' or '}'",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
match *self.peek_token()? {
|
||||
Token(_, TokenType::Key) => {
|
||||
self.skip();
|
||||
if let Token(
|
||||
mark,
|
||||
TokenType::Value | TokenType::FlowEntry | TokenType::FlowMappingEnd,
|
||||
) = *self.peek_token()?
|
||||
{
|
||||
self.state = State::FlowMappingValue;
|
||||
return Ok((Event::empty_scalar(), marker));
|
||||
}
|
||||
Token(_, TokenType::FlowMappingEnd) => (),
|
||||
_ => {
|
||||
self.push_state(State::FlowMappingEmptyValue);
|
||||
return Ok((Event::empty_scalar(), mark));
|
||||
} else {
|
||||
self.push_state(State::FlowMappingValue);
|
||||
return self.parse_node(false, false);
|
||||
}
|
||||
}
|
||||
|
||||
mark
|
||||
Token(marker, TokenType::Value) => {
|
||||
self.state = State::FlowMappingValue;
|
||||
return Ok((Event::empty_scalar(), marker));
|
||||
}
|
||||
Token(_, TokenType::FlowMappingEnd) => (),
|
||||
_ => {
|
||||
self.push_state(State::FlowMappingEmptyValue);
|
||||
return self.parse_node(false, false);
|
||||
}
|
||||
}
|
||||
|
||||
mark
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
self.pop_state();
|
||||
self.skip();
|
||||
|
@ -736,18 +734,16 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
}
|
||||
}
|
||||
self.skip();
|
||||
match *self.peek_token()? {
|
||||
Token(mark, TokenType::BlockEntry)
|
||||
| Token(mark, TokenType::Key)
|
||||
| Token(mark, TokenType::Value)
|
||||
| Token(mark, TokenType::BlockEnd) => {
|
||||
self.state = State::IndentlessSequenceEntry;
|
||||
Ok((Event::empty_scalar(), mark))
|
||||
}
|
||||
_ => {
|
||||
self.push_state(State::IndentlessSequenceEntry);
|
||||
self.parse_node(true, false)
|
||||
}
|
||||
if let Token(
|
||||
mark,
|
||||
TokenType::BlockEntry | TokenType::Key | TokenType::Value | TokenType::BlockEnd,
|
||||
) = *self.peek_token()?
|
||||
{
|
||||
self.state = State::IndentlessSequenceEntry;
|
||||
Ok((Event::empty_scalar(), mark))
|
||||
} else {
|
||||
self.push_state(State::IndentlessSequenceEntry);
|
||||
self.parse_node(true, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -766,15 +762,14 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
}
|
||||
Token(_, TokenType::BlockEntry) => {
|
||||
self.skip();
|
||||
match *self.peek_token()? {
|
||||
Token(mark, TokenType::BlockEntry) | Token(mark, TokenType::BlockEnd) => {
|
||||
self.state = State::BlockSequenceEntry;
|
||||
Ok((Event::empty_scalar(), mark))
|
||||
}
|
||||
_ => {
|
||||
self.push_state(State::BlockSequenceEntry);
|
||||
self.parse_node(true, false)
|
||||
}
|
||||
if let Token(mark, TokenType::BlockEntry | TokenType::BlockEnd) =
|
||||
*self.peek_token()?
|
||||
{
|
||||
self.state = State::BlockSequenceEntry;
|
||||
Ok((Event::empty_scalar(), mark))
|
||||
} else {
|
||||
self.push_state(State::BlockSequenceEntry);
|
||||
self.parse_node(true, false)
|
||||
}
|
||||
}
|
||||
Token(mark, _) => Err(ScanError::new(
|
||||
|
@ -785,18 +780,15 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
}
|
||||
|
||||
fn flow_sequence_entry_mapping_key(&mut self) -> ParseResult {
|
||||
match *self.peek_token()? {
|
||||
Token(mark, TokenType::Value)
|
||||
| Token(mark, TokenType::FlowEntry)
|
||||
| Token(mark, TokenType::FlowSequenceEnd) => {
|
||||
self.skip();
|
||||
self.state = State::FlowSequenceEntryMappingValue;
|
||||
Ok((Event::empty_scalar(), mark))
|
||||
}
|
||||
_ => {
|
||||
self.push_state(State::FlowSequenceEntryMappingValue);
|
||||
self.parse_node(false, false)
|
||||
}
|
||||
if let Token(mark, TokenType::Value | TokenType::FlowEntry | TokenType::FlowSequenceEnd) =
|
||||
*self.peek_token()?
|
||||
{
|
||||
self.skip();
|
||||
self.state = State::FlowSequenceEntryMappingValue;
|
||||
Ok((Event::empty_scalar(), mark))
|
||||
} else {
|
||||
self.push_state(State::FlowSequenceEntryMappingValue);
|
||||
self.parse_node(false, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -805,15 +797,14 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
Token(_, TokenType::Value) => {
|
||||
self.skip();
|
||||
self.state = State::FlowSequenceEntryMappingValue;
|
||||
match *self.peek_token()? {
|
||||
Token(mark, TokenType::FlowEntry) | Token(mark, TokenType::FlowSequenceEnd) => {
|
||||
self.state = State::FlowSequenceEntryMappingEnd;
|
||||
Ok((Event::empty_scalar(), mark))
|
||||
}
|
||||
_ => {
|
||||
self.push_state(State::FlowSequenceEntryMappingEnd);
|
||||
self.parse_node(false, false)
|
||||
}
|
||||
if let Token(mark, TokenType::FlowEntry | TokenType::FlowSequenceEnd) =
|
||||
*self.peek_token()?
|
||||
{
|
||||
self.state = State::FlowSequenceEntryMappingEnd;
|
||||
Ok((Event::empty_scalar(), mark))
|
||||
} else {
|
||||
self.push_state(State::FlowSequenceEntryMappingEnd);
|
||||
self.parse_node(false, false)
|
||||
}
|
||||
}
|
||||
Token(mark, _) => {
|
||||
|
@ -823,6 +814,7 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn flow_sequence_entry_mapping_end(&mut self) -> ParseResult {
|
||||
self.state = State::FlowSequenceEntry;
|
||||
Ok((Event::MappingEnd, self.scanner.mark()))
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#![allow(clippy::cast_possible_wrap)]
|
||||
#![allow(clippy::cast_sign_loss)]
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::error::Error;
|
||||
use std::{char, fmt};
|
||||
|
@ -30,14 +33,17 @@ impl Marker {
|
|||
Marker { index, line, col }
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn index(&self) -> usize {
|
||||
self.index
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn line(&self) -> usize {
|
||||
self.line
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn col(&self) -> usize {
|
||||
self.col
|
||||
}
|
||||
|
@ -50,6 +56,7 @@ pub struct ScanError {
|
|||
}
|
||||
|
||||
impl ScanError {
|
||||
#[must_use]
|
||||
pub fn new(loc: Marker, info: &str) -> ScanError {
|
||||
ScanError {
|
||||
mark: loc,
|
||||
|
@ -57,6 +64,7 @@ impl ScanError {
|
|||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn marker(&self) -> &Marker {
|
||||
&self.mark
|
||||
}
|
||||
|
@ -137,6 +145,7 @@ impl SimpleKey {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
pub struct Scanner<T> {
|
||||
rdr: T,
|
||||
mark: Marker,
|
||||
|
@ -194,19 +203,15 @@ fn is_blankz(c: char) -> bool {
|
|||
}
|
||||
#[inline]
|
||||
fn is_digit(c: char) -> bool {
|
||||
c >= '0' && c <= '9'
|
||||
c.is_ascii_digit()
|
||||
}
|
||||
#[inline]
|
||||
fn is_alpha(c: char) -> bool {
|
||||
match c {
|
||||
'0'..='9' | 'a'..='z' | 'A'..='Z' => true,
|
||||
'_' | '-' => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(c, '0'..='9' | 'a'..='z' | 'A'..='Z' | '_' | '-')
|
||||
}
|
||||
#[inline]
|
||||
fn is_hex(c: char) -> bool {
|
||||
(c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')
|
||||
c.is_ascii_digit() || ('a'..='f').contains(&c) || ('A'..='F').contains(&c)
|
||||
}
|
||||
#[inline]
|
||||
fn as_hex(c: char) -> u32 {
|
||||
|
@ -219,10 +224,7 @@ fn as_hex(c: char) -> u32 {
|
|||
}
|
||||
#[inline]
|
||||
fn is_flow(c: char) -> bool {
|
||||
match c {
|
||||
',' | '[' | ']' | '{' | '}' => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(c, ',' | '[' | ']' | '{' | '}')
|
||||
}
|
||||
|
||||
pub type ScanResult = Result<(), ScanError>;
|
||||
|
@ -251,10 +253,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
|||
}
|
||||
#[inline]
|
||||
pub fn get_error(&self) -> Option<ScanError> {
|
||||
match self.error {
|
||||
None => None,
|
||||
Some(ref e) => Some(e.clone()),
|
||||
}
|
||||
self.error.as_ref().map(std::clone::Clone::clone)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -419,7 +418,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
|||
':' | '?' if !is_blankz(nc) && self.flow_level == 0 => self.fetch_plain_scalar(),
|
||||
'%' | '@' | '`' => Err(ScanError::new(
|
||||
self.mark,
|
||||
&format!("unexpected character: `{}'", c),
|
||||
&format!("unexpected character: `{c}'"),
|
||||
)),
|
||||
_ => self.fetch_plain_scalar(),
|
||||
}
|
||||
|
@ -697,7 +696,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
|||
}
|
||||
|
||||
let is_secondary = handle == "!!";
|
||||
let prefix = self.scan_tag_uri(true, is_secondary, &String::new(), mark)?;
|
||||
let prefix = self.scan_tag_uri(true, is_secondary, "", mark)?;
|
||||
|
||||
self.lookahead(1);
|
||||
|
||||
|
@ -733,7 +732,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
|||
// Eat '!<'
|
||||
self.skip();
|
||||
self.skip();
|
||||
suffix = self.scan_tag_uri(false, false, &String::new(), &start_mark)?;
|
||||
suffix = self.scan_tag_uri(false, false, "", &start_mark)?;
|
||||
|
||||
if self.ch() != '>' {
|
||||
return Err(ScanError::new(
|
||||
|
@ -751,7 +750,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
|||
if handle == "!!" {
|
||||
secondary = true;
|
||||
}
|
||||
suffix = self.scan_tag_uri(false, secondary, &String::new(), &start_mark)?;
|
||||
suffix = self.scan_tag_uri(false, secondary, "", &start_mark)?;
|
||||
} else {
|
||||
suffix = self.scan_tag_uri(false, false, &handle, &start_mark)?;
|
||||
handle = "!".to_owned();
|
||||
|
@ -1072,6 +1071,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn scan_block_scalar(&mut self, literal: bool) -> Result<Token, ScanError> {
|
||||
let start_mark = self.mark;
|
||||
let mut chomping: i32 = 0;
|
||||
|
@ -1280,6 +1280,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn scan_flow_scalar(&mut self, single: bool) -> Result<Token, ScanError> {
|
||||
let start_mark = self.mark;
|
||||
|
||||
|
@ -1389,12 +1390,8 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
|||
value = (value << 4) + as_hex(self.buffer[i]);
|
||||
}
|
||||
|
||||
let ch = match char::from_u32(value) {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
return Err(ScanError::new(start_mark,
|
||||
"while parsing a quoted scalar, found invalid Unicode character escape code"));
|
||||
}
|
||||
let Some(ch) = char::from_u32(value) else {
|
||||
return Err(ScanError::new(start_mark, "while parsing a quoted scalar, found invalid Unicode character escape code"));
|
||||
};
|
||||
string.push(ch);
|
||||
|
||||
|
@ -1739,6 +1736,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(clippy::enum_glob_use)]
|
||||
mod test {
|
||||
use super::TokenType::*;
|
||||
use super::*;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use linked_hash_map::LinkedHashMap;
|
||||
use crate::parser::*;
|
||||
#![allow(clippy::module_name_repetitions)]
|
||||
|
||||
use crate::parser::{Event, MarkedEventReceiver, Parser};
|
||||
use crate::scanner::{Marker, ScanError, TScalarStyle, TokenType};
|
||||
use linked_hash_map::LinkedHashMap;
|
||||
use std::collections::BTreeMap;
|
||||
use std::f64;
|
||||
use std::i64;
|
||||
|
@ -201,6 +203,7 @@ impl YamlLoader {
|
|||
|
||||
macro_rules! define_as (
|
||||
($name:ident, $t:ident, $yt:ident) => (
|
||||
#[must_use]
|
||||
pub fn $name(&self) -> Option<$t> {
|
||||
match *self {
|
||||
Yaml::$yt(v) => Some(v),
|
||||
|
@ -212,6 +215,7 @@ pub fn $name(&self) -> Option<$t> {
|
|||
|
||||
macro_rules! define_as_ref (
|
||||
($name:ident, $t:ty, $yt:ident) => (
|
||||
#[must_use]
|
||||
pub fn $name(&self) -> Option<$t> {
|
||||
match *self {
|
||||
Yaml::$yt(ref v) => Some(v),
|
||||
|
@ -223,6 +227,7 @@ pub fn $name(&self) -> Option<$t> {
|
|||
|
||||
macro_rules! define_into (
|
||||
($name:ident, $t:ty, $yt:ident) => (
|
||||
#[must_use]
|
||||
pub fn $name(self) -> Option<$t> {
|
||||
match self {
|
||||
Yaml::$yt(v) => Some(v),
|
||||
|
@ -246,59 +251,58 @@ impl Yaml {
|
|||
define_into!(into_hash, Hash, Hash);
|
||||
define_into!(into_vec, Array, Array);
|
||||
|
||||
/// Returns the is null of this [`Yaml`].
|
||||
#[must_use]
|
||||
pub fn is_null(&self) -> bool {
|
||||
match *self {
|
||||
Yaml::Null => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(*self, Yaml::Null)
|
||||
}
|
||||
|
||||
/// Returns the is badvalue of this [`Yaml`].
|
||||
#[must_use]
|
||||
pub fn is_badvalue(&self) -> bool {
|
||||
match *self {
|
||||
Yaml::BadValue => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(*self, Yaml::BadValue)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn is_array(&self) -> bool {
|
||||
match *self {
|
||||
Yaml::Array(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(*self, Yaml::Array(_))
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn as_f64(&self) -> Option<f64> {
|
||||
match *self {
|
||||
Yaml::Real(ref v) => parse_f64(v),
|
||||
_ => None,
|
||||
if let Yaml::Real(ref v) = self {
|
||||
parse_f64(v)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn into_f64(self) -> Option<f64> {
|
||||
match self {
|
||||
Yaml::Real(ref v) => parse_f64(v),
|
||||
_ => None,
|
||||
if let Yaml::Real(ref v) = self {
|
||||
parse_f64(v)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "cargo-clippy", allow(should_implement_trait))]
|
||||
#[cfg_attr(feature = "cargo-clippy", allow(clippy::should_implement_trait))]
|
||||
impl Yaml {
|
||||
// Not implementing FromStr because there is no possibility of Error.
|
||||
// This function falls back to Yaml::String if nothing else matches.
|
||||
#[must_use]
|
||||
pub fn from_str(v: &str) -> Yaml {
|
||||
if v.starts_with("0x") {
|
||||
if let Ok(i) = i64::from_str_radix(&v[2..], 16) {
|
||||
if let Some(number) = v.strip_prefix("0x") {
|
||||
if let Ok(i) = i64::from_str_radix(number, 16) {
|
||||
return Yaml::Integer(i);
|
||||
}
|
||||
}
|
||||
if v.starts_with("0o") {
|
||||
if let Ok(i) = i64::from_str_radix(&v[2..], 8) {
|
||||
} else if let Some(number) = v.strip_prefix("0o") {
|
||||
if let Ok(i) = i64::from_str_radix(number, 8) {
|
||||
return Yaml::Integer(i);
|
||||
}
|
||||
}
|
||||
if v.starts_with('+') {
|
||||
if let Ok(i) = v[1..].parse::<i64>() {
|
||||
} else if let Some(number) = v.strip_prefix('+') {
|
||||
if let Ok(i) = number.parse::<i64>() {
|
||||
return Yaml::Integer(i);
|
||||
}
|
||||
}
|
||||
|
@ -306,10 +310,15 @@ impl Yaml {
|
|||
"~" | "null" => Yaml::Null,
|
||||
"true" => Yaml::Boolean(true),
|
||||
"false" => Yaml::Boolean(false),
|
||||
_ if v.parse::<i64>().is_ok() => Yaml::Integer(v.parse::<i64>().unwrap()),
|
||||
// try parsing as f64
|
||||
_ if parse_f64(v).is_some() => Yaml::Real(v.to_owned()),
|
||||
_ => Yaml::String(v.to_owned()),
|
||||
_ => {
|
||||
if let Ok(integer) = v.parse::<i64>() {
|
||||
Yaml::Integer(integer)
|
||||
} else if parse_f64(v).is_some() {
|
||||
Yaml::Real(v.to_owned())
|
||||
} else {
|
||||
Yaml::String(v.to_owned())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -348,7 +357,7 @@ impl IntoIterator for Yaml {
|
|||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
YamlIter {
|
||||
yaml: self.into_vec().unwrap_or_else(Vec::new).into_iter(),
|
||||
yaml: self.into_vec().unwrap_or_default().into_iter(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -366,9 +375,11 @@ impl Iterator for YamlIter {
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(clippy::bool_assert_comparison)]
|
||||
#[allow(clippy::float_cmp)]
|
||||
mod test {
|
||||
use crate::yaml::{vec, Yaml, YamlLoader};
|
||||
use std::f64;
|
||||
use crate::yaml::*;
|
||||
#[test]
|
||||
fn test_coerce() {
|
||||
let s = "---
|
||||
|
@ -376,7 +387,7 @@ a: 1
|
|||
b: 2.2
|
||||
c: [1, 2]
|
||||
";
|
||||
let out = YamlLoader::load_from_str(&s).unwrap();
|
||||
let out = YamlLoader::load_from_str(s).unwrap();
|
||||
let doc = &out[0];
|
||||
assert_eq!(doc["a"].as_i64().unwrap(), 1i64);
|
||||
assert_eq!(doc["b"].as_f64().unwrap(), 2.2f64);
|
||||
|
@ -386,7 +397,7 @@ c: [1, 2]
|
|||
|
||||
#[test]
|
||||
fn test_empty_doc() {
|
||||
let s: String = "".to_owned();
|
||||
let s: String = String::new();
|
||||
YamlLoader::load_from_str(&s).unwrap();
|
||||
let s: String = "---".to_owned();
|
||||
assert_eq!(YamlLoader::load_from_str(&s).unwrap()[0], Yaml::Null);
|
||||
|
@ -425,7 +436,7 @@ a7: 你好
|
|||
---
|
||||
'a scalar'
|
||||
";
|
||||
let out = YamlLoader::load_from_str(&s).unwrap();
|
||||
let out = YamlLoader::load_from_str(s).unwrap();
|
||||
assert_eq!(out.len(), 3);
|
||||
}
|
||||
|
||||
|
@ -437,7 +448,7 @@ a1: &DEFAULT
|
|||
b2: d
|
||||
a2: *DEFAULT
|
||||
";
|
||||
let out = YamlLoader::load_from_str(&s).unwrap();
|
||||
let out = YamlLoader::load_from_str(s).unwrap();
|
||||
let doc = &out[0];
|
||||
assert_eq!(doc["a2"]["b1"].as_i64().unwrap(), 4);
|
||||
}
|
||||
|
@ -449,7 +460,7 @@ a1: &DEFAULT
|
|||
b1: 4
|
||||
b2: *DEFAULT
|
||||
";
|
||||
let out = YamlLoader::load_from_str(&s).unwrap();
|
||||
let out = YamlLoader::load_from_str(s).unwrap();
|
||||
let doc = &out[0];
|
||||
assert_eq!(doc["a1"]["b2"], Yaml::BadValue);
|
||||
}
|
||||
|
@ -458,7 +469,7 @@ a1: &DEFAULT
|
|||
fn test_github_27() {
|
||||
// https://github.com/chyh1990/yaml-rust/issues/27
|
||||
let s = "&a";
|
||||
let out = YamlLoader::load_from_str(&s).unwrap();
|
||||
let out = YamlLoader::load_from_str(s).unwrap();
|
||||
let doc = &out[0];
|
||||
assert_eq!(doc.as_str().unwrap(), "");
|
||||
}
|
||||
|
@ -494,7 +505,7 @@ a1: &DEFAULT
|
|||
- +12345
|
||||
- [ true, false ]
|
||||
";
|
||||
let out = YamlLoader::load_from_str(&s).unwrap();
|
||||
let out = YamlLoader::load_from_str(s).unwrap();
|
||||
let doc = &out[0];
|
||||
|
||||
assert_eq!(doc[0].as_str().unwrap(), "string");
|
||||
|
@ -531,14 +542,14 @@ a1: &DEFAULT
|
|||
fn test_bad_hyphen() {
|
||||
// See: https://github.com/chyh1990/yaml-rust/issues/23
|
||||
let s = "{-";
|
||||
assert!(YamlLoader::load_from_str(&s).is_err());
|
||||
assert!(YamlLoader::load_from_str(s).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_issue_65() {
|
||||
// See: https://github.com/chyh1990/yaml-rust/issues/65
|
||||
let b = "\n\"ll\\\"ll\\\r\n\"ll\\\"ll\\\r\r\r\rU\r\r\rU";
|
||||
assert!(YamlLoader::load_from_str(&b).is_err());
|
||||
assert!(YamlLoader::load_from_str(b).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -582,7 +593,7 @@ a1: &DEFAULT
|
|||
- .NAN
|
||||
- !!float .INF
|
||||
";
|
||||
let mut out = YamlLoader::load_from_str(&s).unwrap().into_iter();
|
||||
let mut out = YamlLoader::load_from_str(s).unwrap().into_iter();
|
||||
let mut doc = out.next().unwrap().into_iter();
|
||||
|
||||
assert_eq!(doc.next().unwrap().into_string().unwrap(), "string");
|
||||
|
@ -614,7 +625,7 @@ b: ~
|
|||
a: ~
|
||||
c: ~
|
||||
";
|
||||
let out = YamlLoader::load_from_str(&s).unwrap();
|
||||
let out = YamlLoader::load_from_str(s).unwrap();
|
||||
let first = out.into_iter().next().unwrap();
|
||||
let mut iter = first.into_hash().unwrap().into_iter();
|
||||
assert_eq!(
|
||||
|
@ -640,7 +651,7 @@ c: ~
|
|||
1:
|
||||
important: false
|
||||
";
|
||||
let out = YamlLoader::load_from_str(&s).unwrap();
|
||||
let out = YamlLoader::load_from_str(s).unwrap();
|
||||
let first = out.into_iter().next().unwrap();
|
||||
assert_eq!(first[0]["important"].as_bool().unwrap(), true);
|
||||
}
|
||||
|
@ -716,10 +727,10 @@ subcommands3:
|
|||
about: server related commands
|
||||
"#;
|
||||
|
||||
let out = YamlLoader::load_from_str(&s).unwrap();
|
||||
let out = YamlLoader::load_from_str(s).unwrap();
|
||||
let doc = &out.into_iter().next().unwrap();
|
||||
|
||||
println!("{:#?}", doc);
|
||||
println!("{doc:#?}");
|
||||
assert_eq!(doc["subcommands"][0]["server"], Yaml::Null);
|
||||
assert!(doc["subcommands2"][0]["server"].as_hash().is_some());
|
||||
assert!(doc["subcommands3"][0]["server"].as_hash().is_some());
|
||||
|
|
|
@ -6,7 +6,7 @@ use yaml_rust::parser::{Event, EventReceiver, Parser};
|
|||
use yaml_rust::scanner::TScalarStyle;
|
||||
|
||||
// These names match the names used in the C++ test suite.
|
||||
#[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
|
||||
#[cfg_attr(feature = "cargo-clippy", allow(clippy::enum_variant_names))]
|
||||
#[derive(Clone, PartialEq, PartialOrd, Debug)]
|
||||
enum TestEvent {
|
||||
OnDocumentStart,
|
||||
|
@ -76,24 +76,18 @@ include!("spec_test.rs.inc");
|
|||
|
||||
#[test]
|
||||
fn test_mapvec_legal() {
|
||||
use yaml_rust::yaml::{Array, Hash, Yaml};
|
||||
use yaml_rust::yaml::{Hash, Yaml};
|
||||
use yaml_rust::{YamlEmitter, YamlLoader};
|
||||
|
||||
// Emitting a `map<map<seq<_>>, _>` should result in legal yaml that
|
||||
// we can parse.
|
||||
|
||||
let mut key = Array::new();
|
||||
key.push(Yaml::Integer(1));
|
||||
key.push(Yaml::Integer(2));
|
||||
key.push(Yaml::Integer(3));
|
||||
let key = vec![Yaml::Integer(1), Yaml::Integer(2), Yaml::Integer(3)];
|
||||
|
||||
let mut keyhash = Hash::new();
|
||||
keyhash.insert(Yaml::String("key".into()), Yaml::Array(key));
|
||||
|
||||
let mut val = Array::new();
|
||||
val.push(Yaml::Integer(4));
|
||||
val.push(Yaml::Integer(5));
|
||||
val.push(Yaml::Integer(6));
|
||||
let val = vec![Yaml::Integer(4), Yaml::Integer(5), Yaml::Integer(6)];
|
||||
|
||||
let mut hash = Hash::new();
|
||||
hash.insert(Yaml::Hash(keyhash), Yaml::Array(val));
|
||||
|
|
|
@ -7,14 +7,14 @@ fn roundtrip(original: &Yaml) {
|
|||
YamlEmitter::new(&mut emitted).dump(original).unwrap();
|
||||
|
||||
let documents = YamlLoader::load_from_str(&emitted).unwrap();
|
||||
println!("emitted {}", emitted);
|
||||
println!("emitted {emitted}");
|
||||
|
||||
assert_eq!(documents.len(), 1);
|
||||
assert_eq!(documents[0], *original);
|
||||
}
|
||||
|
||||
fn double_roundtrip(original: &str) {
|
||||
let parsed = YamlLoader::load_from_str(&original).unwrap();
|
||||
let parsed = YamlLoader::load_from_str(original).unwrap();
|
||||
|
||||
let mut serialized = String::new();
|
||||
YamlEmitter::new(&mut serialized).dump(&parsed[0]).unwrap();
|
||||
|
@ -39,27 +39,32 @@ fn test_colon_in_string() {
|
|||
#[test]
|
||||
fn test_numberlike_strings() {
|
||||
let docs = [
|
||||
r#"x: "1234""#, r#"x: "01234""#, r#""1234""#,
|
||||
r#""01234""#, r#"" 01234""#, r#""0x1234""#,
|
||||
r#"x: "1234""#,
|
||||
r#"x: "01234""#,
|
||||
r#""1234""#,
|
||||
r#""01234""#,
|
||||
r#"" 01234""#,
|
||||
r#""0x1234""#,
|
||||
r#"" 0x1234""#,
|
||||
];
|
||||
|
||||
for doc in &docs {
|
||||
roundtrip(&Yaml::String(doc.to_string()));
|
||||
double_roundtrip(&doc);
|
||||
roundtrip(&Yaml::String((*doc).to_string()));
|
||||
double_roundtrip(doc);
|
||||
}
|
||||
}
|
||||
|
||||
/// Example from https://github.com/chyh1990/yaml-rust/issues/133
|
||||
/// Example from <https://github.com/chyh1990/yaml-rust/issues/133>
|
||||
#[test]
|
||||
fn test_issue133() {
|
||||
|
||||
let doc = YamlLoader::load_from_str("\"0x123\"").unwrap().pop().unwrap();
|
||||
let doc = YamlLoader::load_from_str("\"0x123\"")
|
||||
.unwrap()
|
||||
.pop()
|
||||
.unwrap();
|
||||
assert_eq!(doc, Yaml::String("0x123".to_string()));
|
||||
|
||||
let mut out_str = String::new();
|
||||
YamlEmitter::new(&mut out_str).dump(&doc).unwrap();
|
||||
let doc2 = YamlLoader::load_from_str(&out_str).unwrap().pop().unwrap();
|
||||
assert_eq!(doc, doc2); // This failed because the type has changed to a number now
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue