use std::borrow::Cow; use std::convert::TryFrom; use std::io; use std::marker::PhantomData; use crate::BinarySource; use crate::CompoundClass; use crate::SignedInteger; use crate::Value; use crate::ValueClass; use crate::boundary as B; use crate::domain::Domain; use crate::domain::DomainDecode; use crate::domain::IOValueDomainCodec; use crate::error::Error; use crate::error::ExpectedKind; use crate::error::io_eof; use crate::repr::Annotations; use crate::repr::Atom; use crate::repr::Embedded; use crate::repr::IOValue; use crate::repr::Map; use crate::repr::Record; use crate::repr::Set; use crate::repr::ValueImpl; pub type ReaderResult = std::result::Result; #[derive(Debug, Clone, PartialEq, Eq)] pub enum NextToken { Annotation, Value(ValueClass), } pub trait Reader<'de> { fn peek_class(&mut self) -> io::Result>; fn next_atom(&mut self) -> ReaderResult>; fn boundary(&mut self, b: &B::Type) -> ReaderResult<()>; fn open_record(&mut self) -> ReaderResult<()>; fn open_sequence(&mut self) -> ReaderResult<()>; fn open_set(&mut self) -> ReaderResult<()>; fn open_dictionary(&mut self) -> ReaderResult<()>; // Answers true for closed, false for more. // Implies a b.shift of None if closed or of Some(i) if not closed, plus a .boundary. fn close_compound(&mut self, b: &mut B::Type, i: &B::Item) -> ReaderResult; fn open_embedded(&mut self) -> ReaderResult<()>; fn close_embedded(&mut self) -> ReaderResult<()>; fn open_annotation(&mut self) -> ReaderResult<()>; fn close_annotation(&mut self) -> ReaderResult<()>; fn mark(&mut self) -> io::Result; fn restore(&mut self, mark: usize) -> io::Result<()>; //--------------------------------------------------------------------------- fn skip_atom(&mut self) -> io::Result<()> { let _ = self.next_atom()?; Ok(()) } fn skip_annotations(&mut self) -> io::Result> { loop { match self.peek_class()? { None => return Ok(None), Some(NextToken::Value(v)) => return Ok(Some(v)), Some(NextToken::Annotation) => { self.open_annotation()?; self.skip_value()?; self.close_annotation()?; } } } } fn skip_value(&mut self) -> io::Result<()> { // TODO efficient skipping in specific impls of this trait match self.skip_annotations()?.ok_or_else(io_eof)? { ValueClass::Atomic(_) => self.skip_atom(), ValueClass::Embedded => { self.open_embedded()?; self.skip_value()?; self.close_embedded()?; Ok(()) } ValueClass::Compound(CompoundClass::Record) => { self.open_record()?; let mut b = B::start(B::Item::RecordLabel); self.boundary(&b)?; self.skip_value()?; while !self.close_compound(&mut b, &B::Item::RecordField)? { self.skip_value()?; } Ok(()) } ValueClass::Compound(CompoundClass::Sequence) => { self.open_sequence()?; let mut b = B::Type::default(); while !self.close_compound(&mut b, &B::Item::SequenceValue)? { self.skip_value()?; } Ok(()) } ValueClass::Compound(CompoundClass::Set) => { self.open_set()?; let mut b = B::Type::default(); while !self.close_compound(&mut b, &B::Item::SetValue)? { self.skip_value()?; } Ok(()) } ValueClass::Compound(CompoundClass::Dictionary) => { self.open_dictionary()?; let mut b = B::Type::default(); while !self.close_compound(&mut b, &B::Item::DictionaryKey)? { self.skip_value()?; b.shift(Some(B::Item::DictionaryValue)); self.boundary(&b)?; self.skip_value()?; } Ok(()) } } } fn gather_annotations(&mut self) -> io::Result, ValueClass)>> { let mut anns = Vec::new(); loop { match self.peek_class()? { None => return Ok(None), Some(NextToken::Value(v)) => return Ok(Some((anns, v))), Some(NextToken::Annotation) => { self.open_annotation()?; anns.push(self.next_iovalue(true)?); self.close_annotation()?; } } } } fn next>( &mut self, read_annotations: bool, dec: &mut Dec, ) -> io::Result> { let (anns, v) = match read_annotations { true => self.gather_annotations()?.ok_or_else(io_eof)?, false => (Vec::new(), self.skip_annotations()?.ok_or_else(io_eof)?), }; let value = match v { ValueClass::Atomic(_) => self.next_atom()?.into_value(), ValueClass::Embedded => { self.open_embedded()?; let v = dec.decode_embedded(self, read_annotations)?; self.close_embedded()?; Value::new(Embedded::new(v)) } ValueClass::Compound(CompoundClass::Record) => { let mut vs = Vec::new(); self.open_record()?; let mut b = B::start(B::Item::RecordLabel); self.boundary(&b)?; vs.push(self.next(read_annotations, dec)?); while !self.close_compound(&mut b, &B::Item::RecordField)? { vs.push(self.next(read_annotations, dec)?); } Value::new(Record::_from_vec(vs)) } ValueClass::Compound(CompoundClass::Sequence) => { let mut vs = Vec::new(); self.open_sequence()?; let mut b = B::Type::default(); while !self.close_compound(&mut b, &B::Item::SequenceValue)? { vs.push(self.next(read_annotations, dec)?); } Value::new(vs) } ValueClass::Compound(CompoundClass::Set) => { let mut s = Set::new(); self.open_set()?; let mut b = B::Type::default(); while !self.close_compound(&mut b, &B::Item::SetValue)? { s.insert(self.next(read_annotations, dec)?); } Value::new(s) } ValueClass::Compound(CompoundClass::Dictionary) => { let mut d = Map::new(); self.open_dictionary()?; let mut b = B::Type::default(); while !self.close_compound(&mut b, &B::Item::DictionaryKey)? { let k = self.next(read_annotations, dec)?; b.shift(Some(B::Item::DictionaryValue)); self.boundary(&b)?; d.insert(k, self.next(read_annotations, dec)?); } Value::new(d) } }; if anns.is_empty() { Ok(value) } else { Ok(Annotations::new(value, anns)) } } fn next_iovalue(&mut self, read_annotations: bool) -> io::Result { Ok(self.next(read_annotations, &mut IOValueDomainCodec)?.into()) } fn next_boolean(&mut self) -> ReaderResult { self.next_iovalue(false)?.as_boolean().ok_or(Error::Expected(ExpectedKind::Boolean)) } fn next_float(&mut self) -> ReaderResult { self.next_iovalue(false)?.as_float().ok_or(Error::Expected(ExpectedKind::Float)) } fn next_double(&mut self) -> ReaderResult { self.next_iovalue(false)?.as_double().ok_or(Error::Expected(ExpectedKind::Double)) } fn next_signedinteger(&mut self) -> ReaderResult { Ok(self.next_iovalue(false)?.as_signed_integer().ok_or(Error::Expected(ExpectedKind::SignedInteger))?.into_owned().into()) } fn next_i8(&mut self) -> ReaderResult { Ok(i8::try_from(&self.next_signedinteger()?)?) } fn next_u8(&mut self) -> ReaderResult { Ok(u8::try_from(&self.next_signedinteger()?)?) } fn next_i16(&mut self) -> ReaderResult { Ok(i16::try_from(&self.next_signedinteger()?)?) } fn next_u16(&mut self) -> ReaderResult { Ok(u16::try_from(&self.next_signedinteger()?)?) } fn next_i32(&mut self) -> ReaderResult { Ok(i32::try_from(&self.next_signedinteger()?)?) } fn next_u32(&mut self) -> ReaderResult { Ok(u32::try_from(&self.next_signedinteger()?)?) } fn next_i64(&mut self) -> ReaderResult { Ok(i64::try_from(&self.next_signedinteger()?)?) } fn next_u64(&mut self) -> ReaderResult { Ok(u64::try_from(&self.next_signedinteger()?)?) } fn next_i128(&mut self) -> ReaderResult { Ok(i128::try_from(&self.next_signedinteger()?)?) } fn next_u128(&mut self) -> ReaderResult { Ok(u128::try_from(&self.next_signedinteger()?)?) } fn next_str(&mut self) -> ReaderResult> { Ok(self.next_iovalue(false)?.as_string().ok_or(Error::Expected(ExpectedKind::String))?.into_owned().into()) } fn next_bytestring(&mut self) -> ReaderResult> { Ok(self.next_iovalue(false)?.as_bytestring().ok_or(Error::Expected(ExpectedKind::ByteString))?.into_owned().into()) } fn next_symbol(&mut self) -> ReaderResult> { Ok(self.next_iovalue(false)?.as_symbol().ok_or(Error::Expected(ExpectedKind::Symbol))?.into_owned().into()) } fn open_simple_record(&mut self, name: &str) -> ReaderResult { self.open_record()?; let b = B::start(B::Item::RecordLabel); self.boundary(&b)?; let label: &str = &self.next_symbol()?; if label == name { Ok(b) } else { Err(Error::Expected(ExpectedKind::SimpleRecord(name.to_owned()))) } } fn ensure_more_expected(&mut self, b: &mut B::Type, i: &B::Item) -> ReaderResult<()> { if !self.close_compound(b, i)? { Ok(()) } else { Err(Error::MissingItem) } } fn ensure_complete(&mut self, mut b: B::Type, i: &B::Item) -> ReaderResult<()> { if !self.close_compound(&mut b, i)? { Err(Error::MissingCloseDelimiter) } else { Ok(()) } } fn specialized(&mut self) -> Option<(&str, &mut dyn BinarySource<'de>)> { None } } pub struct IOValues<'de, R: Reader<'de>> { pub reader: R, pub read_annotations: bool, phantom: PhantomData<&'de ()>, } impl<'de, R: Reader<'de>> IOValues<'de, R> { pub fn new(reader: R) -> Self { IOValues { reader, read_annotations: false, phantom: PhantomData, } } pub fn read_annotations(mut self, read_annotations: bool) -> Self { self.read_annotations = read_annotations; self } } impl<'de, R: Reader<'de>> std::iter::Iterator for IOValues<'de, R> { type Item = io::Result; fn next(&mut self) -> Option { match self.reader.peek_class() { Err(e) => Some(Err(e)), Ok(None) => None, Ok(Some(_)) => Some(self.reader.next_iovalue(self.read_annotations)), } } }