preserves/implementations/rust/preserves/src/value/reader.rs

291 lines
9.1 KiB
Rust

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<T> = std::result::Result<T, error::Error>;
pub trait Reader<'de> {
fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>>;
fn open_record(&mut self, arity: Option<usize>) -> 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<bool>;
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<IOValue> {
self.next(read_annotations)?.ok_or_else(io_eof)
}
fn next_boolean(&mut self) -> ReaderResult<bool> { self.demand_next(false)?.value().to_boolean() }
fn next_i8(&mut self) -> ReaderResult<i8> { self.demand_next(false)?.value().to_i8() }
fn next_u8(&mut self) -> ReaderResult<u8> { self.demand_next(false)?.value().to_u8() }
fn next_i16(&mut self) -> ReaderResult<i16> { self.demand_next(false)?.value().to_i16() }
fn next_u16(&mut self) -> ReaderResult<u16> { self.demand_next(false)?.value().to_u16() }
fn next_i32(&mut self) -> ReaderResult<i32> { self.demand_next(false)?.value().to_i32() }
fn next_u32(&mut self) -> ReaderResult<u32> { self.demand_next(false)?.value().to_u32() }
fn next_i64(&mut self) -> ReaderResult<i64> { self.demand_next(false)?.value().to_i64() }
fn next_u64(&mut self) -> ReaderResult<u64> { self.demand_next(false)?.value().to_u64() }
fn next_i128(&mut self) -> ReaderResult<i128> { self.demand_next(false)?.value().to_i128() }
fn next_u128(&mut self) -> ReaderResult<u128> { self.demand_next(false)?.value().to_u128() }
fn next_f32(&mut self) -> ReaderResult<f32> { self.demand_next(false)?.value().to_f32() }
fn next_f64(&mut self) -> ReaderResult<f64> { self.demand_next(false)?.value().to_f64() }
fn next_char(&mut self) -> ReaderResult<char> { self.demand_next(false)?.value().to_char() }
fn next_str(&mut self) -> ReaderResult<Cow<'de, str>> {
Ok(Cow::Owned(self.demand_next(false)?.value().to_string()?.to_owned()))
}
fn next_bytestring(&mut self) -> ReaderResult<Cow<'de, [u8]>> {
Ok(Cow::Owned(self.demand_next(false)?.value().to_bytestring()?.to_owned()))
}
fn next_symbol(&mut self) -> ReaderResult<Cow<'de, str>> {
Ok(Cow::Owned(self.demand_next(false)?.value().to_symbol()?.to_owned()))
}
fn open_option(&mut self) -> ReaderResult<bool>
{
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<usize>) -> 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<Option<IOValue>> {
(*self).next(read_annotations)
}
fn open_record(&mut self, arity: Option<usize>) -> 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<bool> {
(*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<u8>;
fn readbytes(&mut self, count: usize) -> IOResult<Cow<'de, [u8]>>;
fn readbytes_into(&mut self, bs: &mut [u8]) -> IOResult<()>;
}
pub struct IOBinarySource<'a, R: Read> {
pub read: &'a mut R,
pub buf: Option<u8>,
}
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<u8> {
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<Cow<'de, [u8]>> {
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<u8> {
if self.index >= self.bytes.len() {
Err(io_eof())
} else {
Ok(self.bytes[self.index])
}
}
fn readbytes(&mut self, count: usize) -> IOResult<Cow<'de, [u8]>> {
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<IOValue> {
self.reader.demand_next(self.read_annotations)
}
}
impl<'de, R: Reader<'de>> std::iter::Iterator for ConfiguredReader<'de, R> {
type Item = IOResult<IOValue>;
fn next(&mut self) -> Option<Self::Item> {
match self.reader.next(self.read_annotations) {
Err(e) => Some(Err(e)),
Ok(None) => None,
Ok(Some(v)) => Some(Ok(v)),
}
}
}