Skip to content

Commit

Permalink
Merge pull request #75 from chris-m-h/owned-events
Browse files Browse the repository at this point in the history
Allow clients to get ownership of events
  • Loading branch information
dtolnay authored Jun 19, 2017
2 parents 1875fb3 + 7de2c38 commit d9024de
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 47 deletions.
79 changes: 44 additions & 35 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,22 +76,20 @@ pub struct Parser<T> {


pub trait EventReceiver {
fn on_event(&mut self, ev: &Event);
fn on_event(&mut self, ev: Event);
}


pub trait MarkedEventReceiver {
fn on_event(&mut self, ev: &Event, _mark: Marker);
fn on_event(&mut self, ev: Event, _mark: Marker);
}

impl<R: EventReceiver> MarkedEventReceiver for R {
fn on_event(&mut self, ev: &Event, _mark: Marker) {
fn on_event(&mut self, ev: Event, _mark: Marker) {
self.on_event(ev)
}
}



pub type ParseResult = Result<(Event, Marker), ScanError>;

impl<T: Iterator<Item=char>> Parser<T> {
Expand Down Expand Up @@ -136,102 +134,113 @@ impl<T: Iterator<Item=char>> Parser<T> {
self.states.push(state);
}

fn parse<R: MarkedEventReceiver>(&mut self, recv: &mut R)
-> Result<Event, ScanError> {
fn parse(&mut self) -> ParseResult {
if self.state == State::End {
return Ok(Event::StreamEnd);
return Ok((Event::StreamEnd, self.scanner.mark()));
}
let (ev, mark) = try!(self.state_machine());
// println!("EV {:?}", ev);
recv.on_event(&ev, mark);
Ok(ev)
Ok((ev, mark))
}

pub fn load<R: MarkedEventReceiver>(&mut self, recv: &mut R, multi: bool)
-> Result<(), ScanError> {
if !self.scanner.stream_started() {
let ev = try!(self.parse(recv));
let (ev, mark) = try!(self.parse());
assert_eq!(ev, Event::StreamStart);
recv.on_event(ev, mark);
}

if self.scanner.stream_ended() {
// XXX has parsed?
recv.on_event(&Event::StreamEnd, self.scanner.mark());
recv.on_event(Event::StreamEnd, self.scanner.mark());
return Ok(());
}
loop {
let ev = try!(self.parse(recv));
let (ev, mark) = try!(self.parse());
if ev == Event::StreamEnd {
recv.on_event(&Event::StreamEnd, self.scanner.mark());
recv.on_event(ev, mark);
return Ok(());
}
// clear anchors before a new document
self.anchors.clear();
try!(self.load_document(&ev, recv));
try!(self.load_document(ev, mark, recv));
if !multi {
break;
}
}
Ok(())
}

fn load_document<R: MarkedEventReceiver>(&mut self, first_ev: &Event, recv: &mut R)
fn load_document<R: MarkedEventReceiver>(&mut self, first_ev: Event, mark: Marker, recv: &mut R)
-> Result<(), ScanError> {
assert_eq!(first_ev, &Event::DocumentStart);
assert_eq!(first_ev, Event::DocumentStart);
recv.on_event(first_ev, mark);

let ev = try!(self.parse(recv));
try!(self.load_node(&ev, recv));
let (ev, mark) = try!(self.parse());
try!(self.load_node(ev, mark, recv));

// DOCUMENT-END is expected.
let ev = try!(self.parse(recv));
let (ev, mark) = try!(self.parse());
assert_eq!(ev, Event::DocumentEnd);
recv.on_event(ev, mark);

Ok(())
}

fn load_node<R: MarkedEventReceiver>(&mut self, first_ev: &Event, recv: &mut R)
fn load_node<R: MarkedEventReceiver>(&mut self, first_ev: Event, mark: Marker, recv: &mut R)
-> Result<(), ScanError> {
match *first_ev {
match first_ev {
Event::Alias(..) | Event::Scalar(..) => {
recv.on_event(first_ev, mark);
Ok(())
},
Event::SequenceStart(_) => {
self.load_sequence(first_ev, recv)
recv.on_event(first_ev, mark);
self.load_sequence(recv)
},
Event::MappingStart(_) => {
self.load_mapping(first_ev, recv)
recv.on_event(first_ev, mark);
self.load_mapping(recv)
},
_ => { println!("UNREACHABLE EVENT: {:?}", first_ev);
unreachable!(); }
}
}

fn load_mapping<R: MarkedEventReceiver>(&mut self, _first_ev: &Event, recv: &mut R)
fn load_mapping<R: MarkedEventReceiver>(&mut self, recv: &mut R)
-> Result<(), ScanError> {
let mut ev = try!(self.parse(recv));
while ev != Event::MappingEnd {
let (mut key_ev, mut key_mark) = try!(self.parse());
while key_ev != Event::MappingEnd {
// key
try!(self.load_node(&ev, recv));
try!(self.load_node(key_ev, key_mark, recv));

// value
ev = try!(self.parse(recv));
try!(self.load_node(&ev, recv));
let (ev, mark) = try!(self.parse());
try!(self.load_node(ev, mark, recv));

// next event
ev = try!(self.parse(recv));
let (ev, mark) = try!(self.parse());
key_ev = ev;
key_mark = mark;

}
recv.on_event(key_ev, key_mark);
Ok(())
}

fn load_sequence<R: MarkedEventReceiver>(&mut self, _first_ev: &Event, recv: &mut R)
fn load_sequence<R: MarkedEventReceiver>(&mut self, recv: &mut R)
-> Result<(), ScanError> {
let mut ev = try!(self.parse(recv));
let (mut ev, mut mark) = try!(self.parse());
while ev != Event::SequenceEnd {
try!(self.load_node(&ev, recv));
try!(self.load_node(ev, mark, recv));

// next event
ev = try!(self.parse(recv));
let (next_ev, next_mark) = try!(self.parse());
ev = next_ev;
mark = next_mark;
}
recv.on_event(ev, mark);
Ok(())
}

Expand Down
20 changes: 10 additions & 10 deletions src/yaml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ pub struct YamlLoader {
}

impl MarkedEventReceiver for YamlLoader {
fn on_event(&mut self, ev: &Event, _: Marker) {
fn on_event(&mut self, ev: Event, _: Marker) {
// println!("EV {:?}", ev);
match *ev {
match ev {
Event::DocumentStart => {
// do nothing
},
Expand Down Expand Up @@ -106,10 +106,10 @@ impl MarkedEventReceiver for YamlLoader {
let node = self.doc_stack.pop().unwrap();
self.insert_new_node(node);
},
Event::Scalar(ref v, style, aid, ref tag) => {
Event::Scalar(v, style, aid, tag) => {
let node = if style != TScalarStyle::Plain {
Yaml::String(v.clone())
} else if let Some(TokenType::Tag(ref handle, ref suffix)) = *tag {
Yaml::String(v)
} else if let Some(TokenType::Tag(ref handle, ref suffix)) = tag {
// XXX tag:yaml.org,2002:
if handle == "!!" {
match suffix.as_ref() {
Expand All @@ -127,8 +127,8 @@ impl MarkedEventReceiver for YamlLoader {
}
},
"float" => {
match parse_f64(v) {
Some(_) => Yaml::Real(v.clone()),
match parse_f64(&v) {
Some(_) => Yaml::Real(v),
None => Yaml::BadValue,
}
},
Expand All @@ -138,14 +138,14 @@ impl MarkedEventReceiver for YamlLoader {
_ => Yaml::BadValue,
}
}
_ => Yaml::String(v.clone()),
_ => Yaml::String(v),
}
} else {
Yaml::String(v.clone())
Yaml::String(v)
}
} else {
// Datatype is not specified, or unrecognized
Yaml::from_str(v.as_ref())
Yaml::from_str(&v)
};

self.insert_new_node((node, aid));
Expand Down
4 changes: 2 additions & 2 deletions tests/spec_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ struct YamlChecker {
}

impl EventReceiver for YamlChecker {
fn on_event(&mut self, ev: &Event) {
let tev = match *ev {
fn on_event(&mut self, ev: Event) {
let tev = match ev {
Event::DocumentStart => TestEvent::OnDocumentStart,
Event::DocumentEnd => TestEvent::OnDocumentEnd,
Event::SequenceStart(..) => TestEvent::OnSequenceStart,
Expand Down

0 comments on commit d9024de

Please sign in to comment.