use std::borrow::Cow; use std::io::Read; use std::marker::PhantomData; use super::repr::{NestedValue, IOValue}; use super::IOResult; use crate::error::{self, ExpectedKind, Received, io_eof}; pub type ReaderResult = std::result::Result; pub trait Reader<'de> { 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(&mut self) -> ReaderResult; fn open_embedded(&mut self) -> ReaderResult<()>; fn close_embedded(&mut self) -> 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 { self.next(read_annotations)?.ok_or_else(io_eof) } 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_f32(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_f32() } fn next_f64(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_f64() } 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 { self.open_record(None)?; let label: &str = &self.next_symbol()?; match label { "None" => Ok(false), "Some" => Ok(true), _ => Err(error::Error::Expected(ExpectedKind::Option, Received::ReceivedRecordWithLabel(label.to_owned()))), } } fn open_simple_record(&mut self, name: &str, arity: Option) -> ReaderResult<()> { self.open_record(arity)?; let label: &str = &self.next_symbol()?; if label == name { Ok(()) } 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, } } fn skip_remainder(&mut self) -> ReaderResult<()> { while !self.close_compound()? { self.skip_value()?; } Ok(()) } fn ensure_more_expected(&mut self) -> ReaderResult<()> { if !self.close_compound()? { Ok(()) } else { Err(error::Error::MissingItem) } } fn ensure_complete(&mut self) -> ReaderResult<()> { if !self.close_compound()? { Err(error::Error::MissingCloseDelimiter) } else { Ok(()) } } } impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R { 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(&mut self) -> ReaderResult { (*self).close_compound() } fn open_embedded(&mut self) -> ReaderResult<()> { (*self).open_embedded() } fn close_embedded(&mut self) -> ReaderResult<()> { (*self).close_embedded() } } 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 self.buf.is_none() { 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 self.buf.is_some() { 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 self.buf.is_some() { 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)), } } }