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

271 lines
8.8 KiB
Rust

use crate::error::{self, ExpectedKind, io_eof};
use std::borrow::Cow;
use std::io;
use std::marker::PhantomData;
use super::CompoundClass;
use super::DomainDecode;
use super::Double;
use super::DummyValue;
use super::Float;
use super::IOValue;
use super::IOValueDomainCodec;
use super::NestedValue;
use super::boundary as B;
use super::signed_integer::SignedInteger;
pub type ReaderResult<T> = std::result::Result<T, error::Error>;
#[derive(Debug)]
pub enum Token<N: NestedValue> {
Embedded(N::Embedded),
Atom(N),
Compound(CompoundClass),
End,
}
pub trait Reader<'de> {
fn next<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Option<N>>;
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<bool>;
fn open_embedded(&mut self) -> ReaderResult<()>;
fn close_embedded(&mut self) -> ReaderResult<()>;
type Mark;
fn mark(&mut self) -> io::Result<Self::Mark>;
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()>;
fn next_token<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_embedded_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Token<N>>;
//---------------------------------------------------------------------------
fn skip_value(&mut self) -> io::Result<()> {
// TODO efficient skipping in specific impls of this trait
let _: DummyValue<IOValue> = self.demand_next(false, &mut IOValueDomainCodec)?;
Ok(())
}
fn next_iovalue(&mut self, read_annotations: bool) -> io::Result<IOValue> {
self.demand_next(read_annotations, &mut IOValueDomainCodec)
}
fn demand_next<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<N> {
self.next(read_annotations, decode_embedded)?.ok_or_else(io_eof)
}
fn next_boolean(&mut self) -> ReaderResult<bool> {
self.next_iovalue(false)?.value().to_boolean()
}
fn next_float(&mut self) -> ReaderResult<Float> {
Ok(self.next_iovalue(false)?.value().to_float()?.to_owned())
}
fn next_double(&mut self) -> ReaderResult<Double> {
Ok(self.next_iovalue(false)?.value().to_double()?.to_owned())
}
fn next_signedinteger(&mut self) -> ReaderResult<SignedInteger> {
Ok(self.next_iovalue(false)?.value().to_signedinteger()?.to_owned())
}
fn next_i8(&mut self) -> ReaderResult<i8> { self.next_iovalue(false)?.value().to_i8() }
fn next_u8(&mut self) -> ReaderResult<u8> { self.next_iovalue(false)?.value().to_u8() }
fn next_i16(&mut self) -> ReaderResult<i16> { self.next_iovalue(false)?.value().to_i16() }
fn next_u16(&mut self) -> ReaderResult<u16> { self.next_iovalue(false)?.value().to_u16() }
fn next_i32(&mut self) -> ReaderResult<i32> { self.next_iovalue(false)?.value().to_i32() }
fn next_u32(&mut self) -> ReaderResult<u32> { self.next_iovalue(false)?.value().to_u32() }
fn next_i64(&mut self) -> ReaderResult<i64> { self.next_iovalue(false)?.value().to_i64() }
fn next_u64(&mut self) -> ReaderResult<u64> { self.next_iovalue(false)?.value().to_u64() }
fn next_i128(&mut self) -> ReaderResult<i128> { self.next_iovalue(false)?.value().to_i128() }
fn next_u128(&mut self) -> ReaderResult<u128> { self.next_iovalue(false)?.value().to_u128() }
fn next_f32(&mut self) -> ReaderResult<f32> { self.next_iovalue(false)?.value().to_f32() }
fn next_f64(&mut self) -> ReaderResult<f64> { self.next_iovalue(false)?.value().to_f64() }
fn next_char(&mut self) -> ReaderResult<char> { self.next_iovalue(false)?.value().to_char() }
fn next_str(&mut self) -> ReaderResult<Cow<'de, str>> {
Ok(Cow::Owned(self.next_iovalue(false)?.value().to_string()?.to_owned()))
}
fn next_bytestring(&mut self) -> ReaderResult<Cow<'de, [u8]>> {
Ok(Cow::Owned(self.next_iovalue(false)?.value().to_bytestring()?.to_owned()))
}
fn next_symbol(&mut self) -> ReaderResult<Cow<'de, str>> {
Ok(Cow::Owned(self.next_iovalue(false)?.value().to_symbol()?.to_owned()))
}
fn open_simple_record(&mut self, name: &str) -> ReaderResult<()>
{
let b = self.open_record()?;
let label: &str = &self.next_symbol()?;
if label == name {
Ok(b)
} else {
Err(error::Error::Expected(ExpectedKind::SimpleRecord(name.to_owned())))
}
}
fn configured<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
self,
read_annotations: bool,
decode_embedded: Dec,
) -> ConfiguredReader<'de, N, Dec, Self>
where
Self: std::marker::Sized
{
ConfiguredReader {
reader: self,
read_annotations,
decode_embedded,
phantom: PhantomData,
}
}
fn iovalues(self) -> ConfiguredReader<'de, IOValue, IOValueDomainCodec, Self>
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<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Option<N>> {
(*self).next(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<bool> {
(*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> {
(*self).mark()
}
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
(*self).restore(mark)
}
fn next_token<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_embedded_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Token<N>> {
(*self).next_token(read_embedded_annotations, decode_embedded)
}
}
pub struct ConfiguredReader<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>, R: Reader<'de>>
{
pub reader: R,
pub read_annotations: bool,
pub decode_embedded: Dec,
phantom: PhantomData<&'de N>,
}
impl<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>, R: Reader<'de>>
ConfiguredReader<'de, N, Dec, R>
{
pub fn new(reader: R, decode_embedded: Dec) -> Self {
reader.configured(true, decode_embedded)
}
pub fn set_read_annotations(&mut self, read_annotations: bool) {
self.read_annotations = read_annotations;
}
pub fn demand_next(&mut self) -> io::Result<N> {
self.reader.demand_next(self.read_annotations, &mut self.decode_embedded)
}
pub fn next_token(&mut self) -> io::Result<Token<N>> {
self.reader.next_token(self.read_annotations, &mut self.decode_embedded)
}
}
impl<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>, R: Reader<'de>>
std::iter::Iterator
for ConfiguredReader<'de, N, Dec, R>
{
type Item = io::Result<N>;
fn next(&mut self) -> Option<Self::Item> {
match self.reader.next(self.read_annotations, &mut self.decode_embedded) {
Err(e) => Some(Err(e)),
Ok(None) => None,
Ok(Some(v)) => Some(Ok(v)),
}
}
}