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

321 lines
12 KiB
Rust

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<T> = std::result::Result<T, Error>;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum NextToken {
Annotation,
Value(ValueClass),
}
pub trait Reader<'de> {
fn peek_class(&mut self) -> io::Result<Option<NextToken>>;
fn next_atom(&mut self) -> ReaderResult<Atom<'de>>;
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<bool>;
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<usize>;
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<Option<ValueClass>> {
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<Option<(Vec<IOValue>, 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<D: Domain, Dec: DomainDecode<D>>(
&mut self,
read_annotations: bool,
dec: &mut Dec,
) -> io::Result<Value<D>>
{
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<IOValue>
{
Ok(self.next(read_annotations, &mut IOValueDomainCodec)?.into())
}
fn next_boolean(&mut self) -> ReaderResult<bool> {
self.next_iovalue(false)?.as_boolean().ok_or(Error::Expected(ExpectedKind::Boolean))
}
fn next_float(&mut self) -> ReaderResult<f32> {
self.next_iovalue(false)?.as_float().ok_or(Error::Expected(ExpectedKind::Float))
}
fn next_double(&mut self) -> ReaderResult<f64> {
self.next_iovalue(false)?.as_double().ok_or(Error::Expected(ExpectedKind::Double))
}
fn next_signedinteger(&mut self) -> ReaderResult<SignedInteger> {
Ok(self.next_iovalue(false)?.as_signed_integer().ok_or(Error::Expected(ExpectedKind::SignedInteger))?.into_owned().into())
}
fn next_i8(&mut self) -> ReaderResult<i8> { Ok(i8::try_from(&self.next_signedinteger()?)?) }
fn next_u8(&mut self) -> ReaderResult<u8> { Ok(u8::try_from(&self.next_signedinteger()?)?) }
fn next_i16(&mut self) -> ReaderResult<i16> { Ok(i16::try_from(&self.next_signedinteger()?)?) }
fn next_u16(&mut self) -> ReaderResult<u16> { Ok(u16::try_from(&self.next_signedinteger()?)?) }
fn next_i32(&mut self) -> ReaderResult<i32> { Ok(i32::try_from(&self.next_signedinteger()?)?) }
fn next_u32(&mut self) -> ReaderResult<u32> { Ok(u32::try_from(&self.next_signedinteger()?)?) }
fn next_i64(&mut self) -> ReaderResult<i64> { Ok(i64::try_from(&self.next_signedinteger()?)?) }
fn next_u64(&mut self) -> ReaderResult<u64> { Ok(u64::try_from(&self.next_signedinteger()?)?) }
fn next_i128(&mut self) -> ReaderResult<i128> { Ok(i128::try_from(&self.next_signedinteger()?)?) }
fn next_u128(&mut self) -> ReaderResult<u128> { Ok(u128::try_from(&self.next_signedinteger()?)?) }
fn next_str(&mut self) -> ReaderResult<Cow<'de, str>> {
Ok(self.next_iovalue(false)?.as_string().ok_or(Error::Expected(ExpectedKind::String))?.into_owned().into())
}
fn next_bytestring(&mut self) -> ReaderResult<Cow<'de, [u8]>> {
Ok(self.next_iovalue(false)?.as_bytestring().ok_or(Error::Expected(ExpectedKind::ByteString))?.into_owned().into())
}
fn next_symbol(&mut self) -> ReaderResult<Cow<'de, str>> {
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<B::Type>
{
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<IOValue>;
fn next(&mut self) -> Option<Self::Item> {
match self.reader.peek_class() {
Err(e) => Some(Err(e)),
Ok(None) => None,
Ok(Some(_)) => Some(self.reader.next_iovalue(self.read_annotations)),
}
}
}