use std::borrow::Cow; use std::io::{Read, Error}; use std::marker::PhantomData; use super::value::{NestedValue, IOValue}; use crate::error::{self, ExpectedKind, Received, io_eof}; pub type IOResult = std::result::Result; pub type ReaderResult = std::result::Result; pub trait Reader<'de> { type CompoundInfo: Copy; fn next(&mut self, read_annotations: bool) -> IOResult>; fn open_record(&mut self, arity: Option) -> ReaderResult>; fn open_sequence_or_set(&mut self) -> ReaderResult>; fn open_sequence(&mut self) -> ReaderResult>; fn open_set(&mut self) -> ReaderResult>; fn open_dictionary(&mut self) -> ReaderResult>; fn close_compound_counted(&mut self, info: Self::CompoundInfo) -> ReaderResult<()>; fn close_compound_stream(&mut self, info: Self::CompoundInfo) -> ReaderResult; //--------------------------------------------------------------------------- fn skip_value(&mut self) -> IOResult<()> { // TODO efficient skipping in specific impls of this trait let _ = self.demand_next(false)?; Ok(()) } fn demand_next(&mut self, read_annotations: bool) -> IOResult { match self.next(read_annotations)? { None => Err(io_eof()), Some(v) => Ok(v) } } fn next_boolean(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_boolean() } fn next_i8(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_i8() } fn next_u8(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_u8() } fn next_i16(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_i16() } fn next_u16(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_u16() } fn next_i32(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_i32() } fn next_u32(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_u32() } fn next_i64(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_i64() } fn next_u64(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_u64() } fn next_i128(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_i128() } fn next_u128(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_u128() } fn next_float(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_float() } fn next_double(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_double() } fn next_char(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_char() } fn next_str(&mut self) -> ReaderResult> { Ok(Cow::Owned(self.demand_next(false)?.value().to_string()?.to_owned())) } fn next_bytestring(&mut self) -> ReaderResult> { Ok(Cow::Owned(self.demand_next(false)?.value().to_bytestring()?.to_owned())) } fn next_symbol(&mut self) -> ReaderResult> { Ok(Cow::Owned(self.demand_next(false)?.value().to_symbol()?.to_owned())) } fn open_option(&mut self) -> ReaderResult<(bool, CompoundBody)> where Self: Sized { let mut compound_body = self.open_record(None)?; let label: &str = &compound_body.next_symbol(self)?.ok_or(error::Error::MissingItem)?; match label { "None" => Ok((false, compound_body)), "Some" => Ok((true, compound_body)), _ => Err(error::Error::Expected(ExpectedKind::Option, Received::ReceivedRecordWithLabel(label.to_owned()))), } } fn open_simple_record(&mut self, name: &str, arity: Option) -> ReaderResult> where Self: Sized { let mut compound_body = self.open_record(arity)?; let label: &str = &compound_body.next_symbol(self)?.ok_or(error::Error::MissingItem)?; if label == name { Ok(compound_body) } else { Err(error::Error::Expected(ExpectedKind::SimpleRecord(name.to_owned(), arity), Received::ReceivedRecordWithLabel(label.to_owned()))) } } fn configured(self, read_annotations: bool) -> ConfiguredReader<'de, Self> where Self: std::marker::Sized { ConfiguredReader { reader: self, read_annotations, phantom: PhantomData, } } } impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R { type CompoundInfo = R::CompoundInfo; fn next(&mut self, read_annotations: bool) -> IOResult> { (*self).next(read_annotations) } fn open_record(&mut self, arity: Option) -> ReaderResult> { (*self).open_record(arity) } fn open_sequence_or_set(&mut self) -> ReaderResult> { (*self).open_sequence_or_set() } 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 close_compound_counted(&mut self, info: Self::CompoundInfo) -> ReaderResult<()> { (*self).close_compound_counted(info) } fn close_compound_stream(&mut self, info: Self::CompoundInfo) -> ReaderResult { (*self).close_compound_stream(info) } } #[derive(Debug)] pub struct CompoundBody { pub info: I, pub limit: CompoundLimit, } #[derive(Debug)] pub enum CompoundLimit { Counted(usize), Streaming, Finished, } impl CompoundBody { pub fn counted(info: I, size: usize) -> Self { CompoundBody { info, limit: CompoundLimit::Counted(size) } } pub fn streaming(info: I) -> Self { CompoundBody { info, limit: CompoundLimit::Streaming } } pub fn more_expected<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) -> ReaderResult { match self.limit { CompoundLimit::Counted(ref mut n) => if *n == 0 { read.close_compound_counted(self.info)?; self.limit = CompoundLimit::Finished; Ok(false) } else { *n = *n - 1; Ok(true) }, CompoundLimit::Streaming => Ok(!read.close_compound_stream(self.info)?), CompoundLimit::Finished => Ok(false), } } pub fn next_symbol<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) -> ReaderResult>> { match self.more_expected(read)? { false => Ok(None), true => Ok(Some(read.next_symbol()?)), } } pub fn next_value<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R, read_annotations: bool) -> ReaderResult> { match self.more_expected(read)? { false => Ok(None), true => Ok(Some(read.demand_next(read_annotations)?)), } } pub fn remainder<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R, read_annotations: bool) -> ReaderResult> { let mut result = Vec::new(); while let Some(v) = self.next_value(read, read_annotations)? { result.push(v); } Ok(result) } pub fn skip_remainder<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) -> ReaderResult<()> { while let true = self.more_expected(read)? { read.skip_value()?; } Ok(()) } pub fn ensure_more_expected<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) -> ReaderResult<()> { if self.more_expected(read)? { Ok(()) } else { Err(error::Error::MissingItem) } } pub fn ensure_complete<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) -> ReaderResult<()> { if self.more_expected(read)? { Err(error::Error::MissingCloseDelimiter) } else { Ok(()) } } } pub trait BinarySource<'de> { fn skip(&mut self) -> IOResult<()>; fn peek(&mut self) -> IOResult; fn readbytes(&mut self, count: usize) -> IOResult>; fn readbytes_into(&mut self, bs: &mut [u8]) -> IOResult<()>; } pub struct IOBinarySource<'a, R: Read> { pub read: &'a mut R, pub buf: Option, } impl<'a, R: Read> IOBinarySource<'a, R> { pub fn new(read: &'a mut R) -> Self { IOBinarySource { read, buf: None } } } impl<'de, 'a, R: Read> BinarySource<'de> for IOBinarySource<'a, R> { fn skip(&mut self) -> IOResult<()> { if let None = self.buf { unreachable!(); } self.buf = None; Ok(()) } fn peek(&mut self) -> IOResult { match self.buf { Some(b) => Ok(b), None => { let b = &mut [0]; match self.read.read(b)? { 0 => Err(io_eof()), 1 => { self.buf = Some(b[0]); Ok(b[0]) } _ => unreachable!(), } } } } fn readbytes(&mut self, count: usize) -> IOResult> { if let Some(_) = self.buf { unreachable!(); } let mut bs = vec![0; count]; self.read.read_exact(&mut bs)?; Ok(Cow::Owned(bs)) } fn readbytes_into(&mut self, bs: &mut [u8]) -> IOResult<()> { if let Some(_) = self.buf { unreachable!(); } self.read.read_exact(bs) } } pub struct BytesBinarySource<'de> { pub bytes: &'de [u8], pub index: usize, } impl<'de> BytesBinarySource<'de> { pub fn new(bytes: &'de [u8]) -> Self { BytesBinarySource { bytes, index: 0 } } } impl<'de> BinarySource<'de> for BytesBinarySource<'de> { fn skip(&mut self) -> IOResult<()> { if self.index >= self.bytes.len() { unreachable!(); } self.index += 1; Ok(()) } fn peek(&mut self) -> IOResult { if self.index >= self.bytes.len() { Err(io_eof()) } else { Ok(self.bytes[self.index]) } } fn readbytes(&mut self, count: usize) -> IOResult> { if self.index + count > self.bytes.len() { Err(io_eof()) } else { let bs = &self.bytes[self.index..self.index+count]; self.index += count; Ok(Cow::Borrowed(bs)) } } fn readbytes_into(&mut self, bs: &mut [u8]) -> IOResult<()> { let count = bs.len(); if self.index + count > self.bytes.len() { Err(io_eof()) } else { bs.copy_from_slice(&self.bytes[self.index..self.index+count]); self.index += count; Ok(()) } } } pub struct ConfiguredReader<'de, R: Reader<'de>> { pub reader: R, pub read_annotations: bool, phantom: PhantomData<&'de ()>, } impl<'de, R: Reader<'de>> ConfiguredReader<'de, R> { pub fn new(reader: R) -> Self { reader.configured(true) } pub fn set_read_annotations(&mut self, read_annotations: bool) { self.read_annotations = read_annotations } pub fn demand_next(&mut self) -> IOResult { self.reader.demand_next(self.read_annotations) } } impl<'de, R: Reader<'de>> std::iter::Iterator for ConfiguredReader<'de, R> { type Item = IOResult; fn next(&mut self) -> Option { match self.reader.next(self.read_annotations) { Err(e) => Some(Err(e)), Ok(None) => None, Ok(Some(v)) => Some(Ok(v)), } } }