use crate::error::{self, ExpectedKind, io_eof}; use std::borrow::Cow; use std::io; use std::marker::PhantomData; use super::CompoundClass; use super::Domain; use super::DomainDecode; use super::Double; use super::DummyValue; use super::Float; use super::IOValue; use super::IOValueDomainCodec; use super::PlainValue; use super::NestedValue; use super::boundary as B; use super::signed_integer::SignedInteger; pub type ReaderResult = std::result::Result; #[derive(Debug)] pub enum Token { Embedded(D), // TODO: remove use of PlainValue here by structuring Value differently, with a ValueAtom type or similar Atom(PlainValue), Compound(CompoundClass), End, } pub trait Reader<'de> { fn next_domain>( &mut self, read_annotations: bool, decode_embedded: &mut Dec, ) -> io::Result>; fn open_record(&mut self) -> ReaderResult<()>; // followed by label, then fields fn open_sequence(&mut self) -> ReaderResult<()>; // followed by items fn open_set(&mut self) -> ReaderResult<()>; // followed by items fn open_dictionary(&mut self) -> ReaderResult<()>; // followed by key/value pairs fn boundary(&mut self, b: &B::Type) -> 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<()>; type Mark; fn mark(&mut self) -> io::Result; fn restore(&mut self, mark: &Self::Mark) -> io::Result<()>; fn next_token>( &mut self, read_embedded_annotations: bool, decode_embedded: &mut Dec, ) -> io::Result>; //--------------------------------------------------------------------------- fn skip_value(&mut self) -> io::Result<()> { // TODO efficient skipping in specific impls of this trait let _ = self.demand_next::(false)?; Ok(()) } fn next_iovalue(&mut self, read_annotations: bool) -> io::Result { self.demand_next(read_annotations) } fn next(&mut self, read_annotations: bool) -> io::Result> { self.next_domain(read_annotations, &mut ::Decode::default()) } fn demand_next(&mut self, read_annotations: bool) -> io::Result { self.next(read_annotations)?.ok_or_else(io_eof) } fn demand_next_domain>( &mut self, read_annotations: bool, decode_embedded: &mut Dec, ) -> io::Result { self.next_domain(read_annotations, decode_embedded)?.ok_or_else(io_eof) } fn next_boolean(&mut self) -> ReaderResult { self.next_iovalue(false)?.value().to_boolean() } fn next_float(&mut self) -> ReaderResult { Ok(self.next_iovalue(false)?.value().to_float()?.to_owned()) } fn next_double(&mut self) -> ReaderResult { Ok(self.next_iovalue(false)?.value().to_double()?.to_owned()) } fn next_signedinteger(&mut self) -> ReaderResult { Ok(self.next_iovalue(false)?.value().to_signedinteger()?.to_owned()) } fn next_i8(&mut self) -> ReaderResult { self.next_iovalue(false)?.value().to_i8() } fn next_u8(&mut self) -> ReaderResult { self.next_iovalue(false)?.value().to_u8() } fn next_i16(&mut self) -> ReaderResult { self.next_iovalue(false)?.value().to_i16() } fn next_u16(&mut self) -> ReaderResult { self.next_iovalue(false)?.value().to_u16() } fn next_i32(&mut self) -> ReaderResult { self.next_iovalue(false)?.value().to_i32() } fn next_u32(&mut self) -> ReaderResult { self.next_iovalue(false)?.value().to_u32() } fn next_i64(&mut self) -> ReaderResult { self.next_iovalue(false)?.value().to_i64() } fn next_u64(&mut self) -> ReaderResult { self.next_iovalue(false)?.value().to_u64() } fn next_i128(&mut self) -> ReaderResult { self.next_iovalue(false)?.value().to_i128() } fn next_u128(&mut self) -> ReaderResult { self.next_iovalue(false)?.value().to_u128() } fn next_f32(&mut self) -> ReaderResult { self.next_iovalue(false)?.value().to_f32() } fn next_f64(&mut self) -> ReaderResult { self.next_iovalue(false)?.value().to_f64() } fn next_char(&mut self) -> ReaderResult { self.next_iovalue(false)?.value().to_char() } fn next_str(&mut self) -> ReaderResult> { Ok(Cow::Owned(self.next_iovalue(false)?.value().to_string()?.to_owned())) } fn next_bytestring(&mut self) -> ReaderResult> { Ok(Cow::Owned(self.next_iovalue(false)?.value().to_bytestring()?.to_owned())) } fn next_symbol(&mut self) -> ReaderResult> { Ok(Cow::Owned(self.next_iovalue(false)?.value().to_symbol()?.to_owned())) } fn open_simple_record(&mut self, name: &str) -> ReaderResult<()> { self.open_record()?; let label: &str = &self.next_symbol()?; if label == name { Ok(()) } else { Err(error::Error::Expected(ExpectedKind::SimpleRecord(name.to_owned()))) } } fn configured>(self, read_annotations: bool, decode_embedded: Dec) -> ConfiguredReader<'de, N, Self, Dec> where Self: std::marker::Sized { ConfiguredReader { reader: self, read_annotations, decode_embedded, phantom: PhantomData, } } fn iovalues(self) -> ConfiguredReader<'de, IOValue, Self, IOValueDomainCodec> where Self: Sized { self.configured(true, IOValueDomainCodec) } fn ensure_more_expected(&mut self, b: &mut B::Type, i: &B::Item) -> ReaderResult<()> { if !self.close_compound(b, i)? { Ok(()) } else { Err(error::Error::MissingItem) } } fn ensure_complete(&mut self, mut b: B::Type, i: &B::Item) -> ReaderResult<()> { if !self.close_compound(&mut b, i)? { Err(error::Error::MissingCloseDelimiter) } else { Ok(()) } } } impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R { fn next_domain>( &mut self, read_annotations: bool, decode_embedded: &mut Dec, ) -> io::Result> { (*self).next_domain(read_annotations, decode_embedded) } fn open_record(&mut self) -> ReaderResult<()> { (*self).open_record() } fn open_sequence(&mut self) -> ReaderResult<()> { (*self).open_sequence() } fn open_set(&mut self) -> ReaderResult<()> { (*self).open_set() } fn open_dictionary(&mut self) -> ReaderResult<()> { (*self).open_dictionary() } fn boundary(&mut self, b: &B::Type) -> ReaderResult<()> { (*self).boundary(b) } fn close_compound(&mut self, b: &mut B::Type, i: &B::Item) -> ReaderResult { (*self).close_compound(b, i) } fn open_embedded(&mut self) -> ReaderResult<()> { (*self).open_embedded() } fn close_embedded(&mut self) -> ReaderResult<()> { (*self).close_embedded() } type Mark = R::Mark; fn mark(&mut self) -> io::Result { (*self).mark() } fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> { (*self).restore(mark) } fn next_token>( &mut self, read_embedded_annotations: bool, decode_embedded: &mut Dec, ) -> io::Result> { (*self).next_token(read_embedded_annotations, decode_embedded) } } pub struct ConfiguredReader<'de, N: NestedValue, R: Reader<'de>, Dec: DomainDecode = <::Embedded as Domain>::Decode> { pub reader: R, pub read_annotations: bool, pub decode_embedded: Dec, phantom: PhantomData<&'de N>, } impl<'de, N: NestedValue, R: Reader<'de>> ConfiguredReader<'de, N, R> { pub fn new_default(reader: R) -> Self { reader.configured(true, <::Embedded as Domain>::Decode::default()) } } impl<'de, N: NestedValue, Dec: DomainDecode, R: Reader<'de>> ConfiguredReader<'de, N, R, Dec> { pub fn new(reader: R, decode_embedded: Dec) -> Self { reader.configured(true, decode_embedded) } pub fn read_annotations(mut self, read_annotations: bool) -> Self { self.read_annotations = read_annotations; self } pub fn demand_next(&mut self) -> io::Result { self.reader.demand_next_domain(self.read_annotations, &mut self.decode_embedded) } pub fn next_token(&mut self) -> io::Result> { self.reader.next_token(self.read_annotations, &mut self.decode_embedded) } } impl<'de, N: NestedValue, Dec: DomainDecode, R: Reader<'de>> std::iter::Iterator for ConfiguredReader<'de, N, R, Dec> { type Item = io::Result; fn next(&mut self) -> Option { match self.reader.next_domain(self.read_annotations, &mut self.decode_embedded) { Err(e) => Some(Err(e)), Ok(None) => None, Ok(Some(v)) => Some(Ok(v)), } } }