Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ matrix:
- rust: stable
- rust: beta
- rust: nightly
- rust: 1.17.0
script: cargo build
- rust: 1.24.1
- rust: 1.27.0
script:
cargo build
- rust: 1.28.0
- rust: nightly
env: CLIPPY
script: |
Expand Down
4 changes: 2 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
install:
- ps: Start-FileDownload 'https://static.rust-lang.org/dist/rust-1.24.1-i686-pc-windows-gnu.exe'
- rust-1.24.1-i686-pc-windows-gnu.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
- ps: Start-FileDownload 'https://static.rust-lang.org/dist/rust-1.28.0-i686-pc-windows-gnu.exe'
- rust-1.28.0-i686-pc-windows-gnu.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
- SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin
- SET PATH=%PATH%;C:\MinGW\bin
- rustc -V
Expand Down
2 changes: 1 addition & 1 deletion examples/dump_yaml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fn print_indent(indent: usize) {
}
}

fn dump_node(doc: &yaml::Yaml, indent: usize) {
pub fn dump_node(doc: &yaml::Yaml, indent: usize) {
match *doc {
yaml::Yaml::Array(ref v) => {
for x in v {
Expand Down
63 changes: 63 additions & 0 deletions examples/include_file_tag.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
extern crate yaml_rust;

mod dump_yaml;

use std::path::Path;
use std::fs::File;
use std::io::Read;
use std::env;
use yaml_rust::yaml;
use yaml_rust::scanner;

struct IncludeParser<'a> {
root: &'a Path
}

impl<'a> IncludeParser<'a> {
fn new(root: &'a Path) -> IncludeParser {
IncludeParser {
root: root
}
}
}

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 == "!" || *handle == "yaml-rust.include.prefix") && *suffix == "include" {
let mut content = String::new();
return Some(match File::open(self.root.join(value)){
Ok(mut f) => {
let _ = f.read_to_string(&mut content);
let mut loader = yaml::YamlLoader::new();
loader.register_scalar_parser(self);
match loader.parse_from_str(&content.to_owned()) {
Ok(mut docs) => docs.pop().unwrap(),
Err(_) => yaml::Yaml::BadValue
}
}
Err(_) => yaml::Yaml::BadValue
})
}
}
None
}
}

fn main() {
let args: Vec<_> = env::args().collect();
let mut f = File::open(&args[1]).unwrap();
let mut s = String::new();
f.read_to_string(&mut s).unwrap();

let p = env::current_dir().unwrap();
let parser = IncludeParser::new(p.as_path());
let mut loader = yaml::YamlLoader::new();
loader.register_scalar_parser(&parser);

let docs = loader.parse_from_str(&s).unwrap();
for doc in &docs {
println!("---");
dump_yaml::dump_node(doc, 0);
}
}
15 changes: 7 additions & 8 deletions src/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ impl Error for EmitError {
}
}

fn cause(&self) -> Option<&Error> {
fn cause(&self) -> Option<&dyn Error> {
None
}
}
Expand All @@ -38,7 +38,7 @@ impl From<fmt::Error> for EmitError {
}

pub struct YamlEmitter<'a> {
writer: &'a mut fmt::Write,
writer: &'a mut dyn fmt::Write,
best_indent: usize,
compact: bool,

Expand All @@ -48,7 +48,7 @@ pub struct YamlEmitter<'a> {
pub type EmitResult = Result<(), EmitError>;

// from serialize::json
fn escape_str(wr: &mut fmt::Write, v: &str) -> Result<(), fmt::Error> {
fn escape_str(wr: &mut dyn fmt::Write, v: &str) -> Result<(), fmt::Error> {
wr.write_str("\"")?;

let mut start = 0;
Expand Down Expand Up @@ -111,7 +111,7 @@ fn escape_str(wr: &mut fmt::Write, v: &str) -> Result<(), fmt::Error> {
}

impl<'a> YamlEmitter<'a> {
pub fn new(writer: &'a mut fmt::Write) -> YamlEmitter {
pub fn new(writer: &'a mut dyn fmt::Write) -> YamlEmitter {
YamlEmitter {
writer,
best_indent: 2,
Expand Down Expand Up @@ -316,12 +316,12 @@ fn need_quotes(string: &str) -> bool {
| '\"'
| '\''
| '\\'
| '\0'...'\x06'
| '\0'..='\x06'
| '\t'
| '\n'
| '\r'
| '\x0e'...'\x1a'
| '\x1c'...'\x1f' => true,
| '\x0e'..='\x1a'
| '\x1c'..='\x1f' => true,
_ => false,
})
|| [
Expand Down Expand Up @@ -637,5 +637,4 @@ a:

assert_eq!(s, writer);
}

}
46 changes: 41 additions & 5 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub struct Parser<T> {
current: Option<(Event, Marker)>,
anchors: HashMap<String, usize>,
anchor_id: usize,
tag_directives: HashMap<String, String>,
}

pub trait EventReceiver {
Expand Down Expand Up @@ -103,6 +104,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 @@ -365,23 +367,40 @@ impl<T: Iterator<Item = char>> Parser<T> {
}

fn parser_process_directives(&mut self) -> Result<(), ScanError> {
enum DirectiveAction {
None,
Tag { handle: String, prefix: String },
}

loop {
match self.peek_token()?.1 {
// Without NLL, split the peek and the action
let action = match self.peek_token()?.1 {
TokenType::VersionDirective(_, _) => {
// XXX parsing with warning according to spec
//if major != 1 || minor > 2 {
// return Err(ScanError::new(tok.0,
// "found incompatible YAML document"));
//}
DirectiveAction::None
}
TokenType::TagDirective(..) => {
// TODO add tag directive
TokenType::TagDirective(ref handle, ref prefix) => {
let handle = String::clone(handle);
let mut prefix = String::clone(prefix);
prefix.pop();
DirectiveAction::Tag { handle, prefix }
}
_ => break,
};

match action {
DirectiveAction::Tag { handle, prefix } => {
self.tag_directives.insert(handle, prefix);
}
_ => (),
}

self.skip();
}
// TODO tag directive
Ok(())
}

Expand Down Expand Up @@ -502,7 +521,24 @@ impl<T: Iterator<Item = char>> Parser<T> {
Token(_, TokenType::Scalar(..)) => {
self.pop_state();
if let Token(mark, TokenType::Scalar(style, v)) = self.fetch_token() {
Ok((Event::Scalar(v, style, anchor_id, tag), mark))
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)
},
mark,
))
} else {
unreachable!()
}
Expand Down
10 changes: 5 additions & 5 deletions src/scanner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ impl Error for ScanError {
self.info.as_ref()
}

fn cause(&self) -> Option<&Error> {
fn cause(&self) -> Option<&dyn Error> {
None
}
}
Expand Down Expand Up @@ -199,7 +199,7 @@ fn is_digit(c: char) -> bool {
#[inline]
fn is_alpha(c: char) -> bool {
match c {
'0'...'9' | 'a'...'z' | 'A'...'Z' => true,
'0'..='9' | 'a'..='z' | 'A'..='Z' => true,
'_' | '-' => true,
_ => false,
}
Expand All @@ -211,9 +211,9 @@ fn is_hex(c: char) -> bool {
#[inline]
fn as_hex(c: char) -> u32 {
match c {
'0'...'9' => (c as u32) - ('0' as u32),
'a'...'f' => (c as u32) - ('a' as u32) + 10,
'A'...'F' => (c as u32) - ('A' as u32) + 10,
'0'..='9' => (c as u32) - ('0' as u32),
'a'..='f' => (c as u32) - ('a' as u32) + 10,
'A'..='F' => (c as u32) - ('A' as u32) + 10,
_ => unreachable!(),
}
}
Expand Down
Loading