Allow clients ownership of events

Also: Optimize built-in Yaml deserializer to avoid one scalar value cloning step.
This commit is contained in:
Christian Hofer 2017-06-14 10:29:27 +02:00
parent fd047060de
commit 28d17fa242
2 changed files with 62 additions and 42 deletions

View file

@ -90,6 +90,15 @@ impl<R: EventReceiver> MarkedEventReceiver for R {
} }
} }
pub trait MarkedOwnedEventReceiver {
fn on_owned_event(&mut self, ev: Event, _mark: Marker);
}
impl<R: MarkedEventReceiver> MarkedOwnedEventReceiver for R {
fn on_owned_event(&mut self, ev: Event, _mark: Marker) {
self.on_event(&ev, _mark);
}
}
pub type ParseResult = Result<(Event, Marker), ScanError>; pub type ParseResult = Result<(Event, Marker), ScanError>;
@ -136,38 +145,37 @@ impl<T: Iterator<Item=char>> Parser<T> {
self.states.push(state); self.states.push(state);
} }
fn parse<R: MarkedEventReceiver>(&mut self, recv: &mut R) fn parse(&mut self) -> Result<(Event, Marker), ScanError> {
-> Result<Event, ScanError> {
if self.state == State::End { if self.state == State::End {
return Ok(Event::StreamEnd); return Ok((Event::StreamEnd, self.scanner.mark()));
} }
let (ev, mark) = try!(self.state_machine()); let (ev, mark) = try!(self.state_machine());
// println!("EV {:?}", ev); // println!("EV {:?}", ev);
recv.on_event(&ev, mark); Ok((ev, mark))
Ok(ev)
} }
pub fn load<R: MarkedEventReceiver>(&mut self, recv: &mut R, multi: bool) pub fn load<R: MarkedOwnedEventReceiver>(&mut self, recv: &mut R, multi: bool)
-> Result<(), ScanError> { -> Result<(), ScanError> {
if !self.scanner.stream_started() { if !self.scanner.stream_started() {
let ev = try!(self.parse(recv)); let (ev, mark) = try!(self.parse());
assert_eq!(ev, Event::StreamStart); assert_eq!(ev, Event::StreamStart);
recv.on_owned_event(ev, mark);
} }
if self.scanner.stream_ended() { if self.scanner.stream_ended() {
// XXX has parsed? // XXX has parsed?
recv.on_event(&Event::StreamEnd, self.scanner.mark()); recv.on_owned_event(Event::StreamEnd, self.scanner.mark());
return Ok(()); return Ok(());
} }
loop { loop {
let ev = try!(self.parse(recv)); let (ev, mark) = try!(self.parse());
if ev == Event::StreamEnd { if ev == Event::StreamEnd {
recv.on_event(&Event::StreamEnd, self.scanner.mark()); recv.on_owned_event(ev, mark);
return Ok(()); return Ok(());
} }
// clear anchors before a new document // clear anchors before a new document
self.anchors.clear(); self.anchors.clear();
try!(self.load_document(&ev, recv)); try!(self.load_document(ev, mark, recv));
if !multi { if !multi {
break; break;
} }
@ -175,63 +183,75 @@ impl<T: Iterator<Item=char>> Parser<T> {
Ok(()) Ok(())
} }
fn load_document<R: MarkedEventReceiver>(&mut self, first_ev: &Event, recv: &mut R) fn load_document<R: MarkedOwnedEventReceiver>(&mut self, first_ev: Event, mark: Marker, recv: &mut R)
-> Result<(), ScanError> { -> Result<(), ScanError> {
assert_eq!(first_ev, &Event::DocumentStart); assert_eq!(first_ev, Event::DocumentStart);
recv.on_owned_event(first_ev, mark);
let ev = try!(self.parse(recv)); let (ev, mark) = try!(self.parse());
try!(self.load_node(&ev, recv)); try!(self.load_node(ev, mark, recv));
// DOCUMENT-END is expected. // DOCUMENT-END is expected.
let ev = try!(self.parse(recv)); let (ev, mark) = try!(self.parse());
assert_eq!(ev, Event::DocumentEnd); assert_eq!(ev, Event::DocumentEnd);
recv.on_owned_event(ev, mark);
Ok(()) Ok(())
} }
fn load_node<R: MarkedEventReceiver>(&mut self, first_ev: &Event, recv: &mut R) fn load_node<R: MarkedOwnedEventReceiver>(&mut self, first_ev: Event, mark: Marker, recv: &mut R)
-> Result<(), ScanError> { -> Result<(), ScanError> {
match *first_ev { match first_ev {
Event::Alias(..) | Event::Scalar(..) => { Event::Alias(..) | Event::Scalar(..) => {
recv.on_owned_event(first_ev, mark);
Ok(()) Ok(())
}, },
Event::SequenceStart(_) => { Event::SequenceStart(_) => {
self.load_sequence(first_ev, recv) recv.on_owned_event(first_ev, mark);
self.load_sequence(recv)
}, },
Event::MappingStart(_) => { Event::MappingStart(_) => {
self.load_mapping(first_ev, recv) recv.on_owned_event(first_ev, mark);
self.load_mapping(recv)
}, },
_ => { println!("UNREACHABLE EVENT: {:?}", first_ev); _ => { println!("UNREACHABLE EVENT: {:?}", first_ev);
unreachable!(); } unreachable!(); }
} }
} }
fn load_mapping<R: MarkedEventReceiver>(&mut self, _first_ev: &Event, recv: &mut R) fn load_mapping<R: MarkedOwnedEventReceiver>(&mut self, recv: &mut R)
-> Result<(), ScanError> { -> Result<(), ScanError> {
let mut ev = try!(self.parse(recv)); let (mut key_ev, mut key_mark) = try!(self.parse());
while ev != Event::MappingEnd { while key_ev != Event::MappingEnd {
// key // key
try!(self.load_node(&ev, recv)); try!(self.load_node(key_ev, key_mark, recv));
// value // value
ev = try!(self.parse(recv)); let (ev, mark) = try!(self.parse());
try!(self.load_node(&ev, recv)); try!(self.load_node(ev, mark, recv));
// next event // next event
ev = try!(self.parse(recv)); let (ev, mark) = try!(self.parse());
key_ev = ev;
key_mark = mark;
} }
recv.on_owned_event(key_ev, key_mark);
Ok(()) Ok(())
} }
fn load_sequence<R: MarkedEventReceiver>(&mut self, _first_ev: &Event, recv: &mut R) fn load_sequence<R: MarkedOwnedEventReceiver>(&mut self, recv: &mut R)
-> Result<(), ScanError> { -> Result<(), ScanError> {
let mut ev = try!(self.parse(recv)); let (mut ev, mut mark) = try!(self.parse());
while ev != Event::SequenceEnd { while ev != Event::SequenceEnd {
try!(self.load_node(&ev, recv)); try!(self.load_node(ev, mark, recv));
// next event // next event
ev = try!(self.parse(recv)); let (next_ev, next_mark) = try!(self.parse());
ev = next_ev;
mark = next_mark;
} }
recv.on_owned_event(ev, mark);
Ok(()) Ok(())
} }

View file

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