use std::borrow::Cow;
use std::convert::TryFrom;
use std::convert::TryInto;
use std::io;
use std::marker::PhantomData;
use crate::Atom;
use crate::BinarySource;
use crate::BytesBinarySource;
use crate::CompoundClass;
use crate::Domain;
use crate::DomainDecode;
use crate::IOValue;
use crate::SignedInteger;
use crate::Value;
use crate::ValueClass;
use crate::boundary as B;
use crate::error::Error;
use crate::error::SyntaxError;
use crate::error::ExpectedKind;
use crate::error::UnexpectedKind;
use crate::signed_integer::OutOfRange;
pub type ReaderResult<T> = std::result::Result<T, Error>;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum NextToken {
Annotation,
Value(ValueClass),
End,
}
pub enum FullToken<'de> {
Embedded,
Atom(Atom<'de>),
Compound(CompoundClass),
End,
}
pub trait ValueReader<D: Domain> {
fn read<'de, R: Reader<'de> + ?Sized, Dec: DomainDecode<D>>(
r: &mut R,
read_annotations: bool,
dec: &mut Dec,
) -> ReaderResult<Value<D>>;
fn read_text<Dec: DomainDecode<D>>(
s: &str,
read_annotations: bool,
dec: &mut Dec,
) -> ReaderResult<Value<D>> {
Ok(Self::read(&mut BytesBinarySource::new(s.as_bytes()).text(), read_annotations, dec)?)
}
fn read_packed<Dec: DomainDecode<D>>(
bs: &[u8],
read_annotations: bool,
dec: &mut Dec,
) -> ReaderResult<Value<D>> {
Ok(Self::read(&mut BytesBinarySource::new(bs).packed(), read_annotations, dec)?)
}
}
pub trait IOValueReader: ValueReader<IOValue> {
fn read_iovalue<'de, R: Reader<'de> + ?Sized>(
r: &mut R,
read_annotations: bool,
) -> ReaderResult<IOValue>;
fn read_iovalue_text(s: &str, read_annotations: bool) -> ReaderResult<IOValue> {
Ok(Self::read_iovalue(&mut BytesBinarySource::new(s.as_bytes()).text(), read_annotations)?)
}
fn read_iovalue_packed(bs: &[u8], read_annotations: bool) -> ReaderResult<IOValue> {
Ok(Self::read_iovalue(&mut BytesBinarySource::new(bs).packed(), read_annotations)?)
}
fn gather_annotations<'de, R: Reader<'de> + ?Sized>(
r: &mut R,
) -> ReaderResult<Option<(Vec<IOValue>, ValueClass)>> {
let mut anns = Vec::new();
loop {
match r.peek_class()? {
Some(NextToken::Annotation) => {
r.open_annotation()?;
anns.push(Self::read_iovalue(r, true)?);
r.close_annotation()?;
}
Some(NextToken::Value(v)) => return Ok(Some((anns, v))),
Some(NextToken::End) => return Err(r.wrap_syntax_error(
SyntaxError::Unexpected(UnexpectedKind::CloseDelimiter))),
None => return Ok(None),
}
}
}
}
pub trait Reader<'de> {
type ValueReader<D: Domain>: ValueReader<D>;
type IOValueReader: IOValueReader;
fn peek_class(&mut self) -> ReaderResult<Option<NextToken>>;
fn skip_atom(&mut self) -> ReaderResult<()>;
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<()>;
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 wrap_syntax_error(&mut self, e: SyntaxError) -> Error;
fn has_next(&mut self) -> ReaderResult<bool> {
Ok(self.peek_class()?.is_some())
}
fn next<D: Domain, Dec: DomainDecode<D>>(
&mut self,
read_annotations: bool,
dec: &mut Dec,
) -> ReaderResult<Value<D>> {
Self::ValueReader::read(self, read_annotations, dec)
}
fn next_iovalue(&mut self, read_annotations: bool) -> ReaderResult<IOValue> {
Self::IOValueReader::read_iovalue(self, read_annotations)
}
fn try_next<D: Domain, Dec: DomainDecode<D>>(
&mut self,
read_annotations: bool,
dec: &mut Dec,
) -> ReaderResult<Option<Value<D>>> {
Ok(self.has_next()?.then(
|| Self::ValueReader::read(self, read_annotations, dec)).transpose()?)
}
fn try_next_iovalue(&mut self, read_annotations: bool) -> ReaderResult<Option<IOValue>> {
Ok(self.has_next()?.then(
|| Self::IOValueReader::read_iovalue(self, read_annotations)).transpose()?)
}
fn read_all<D: Domain, Dec: DomainDecode<D>>(
&mut self,
read_annotations: bool,
dec: &mut Dec,
) -> ReaderResult<Vec<Value<D>>> {
let mut vs = Vec::new();
while self.has_next()? { vs.push(self.next(read_annotations, dec)?); }
Ok(vs)
}
fn read_all_iovalues(
&mut self,
read_annotations: bool,
) -> ReaderResult<Vec<IOValue>> {
let mut vs = Vec::new();
while self.has_next()? { vs.push(self.next_iovalue(read_annotations)?); }
Ok(vs)
}
fn next_full_token(&mut self) -> ReaderResult<FullToken<'de>> {
match self.skip_annotations() {
Ok(Some(ValueClass::Atomic(_))) => Ok(FullToken::Atom(self.next_atom()?)),
Ok(Some(ValueClass::Compound(c))) => Ok(FullToken::Compound(c)),
Ok(Some(ValueClass::Embedded)) => Ok(FullToken::Embedded),
Ok(None) => Err(self.wrap_syntax_error(SyntaxError::eof())),
Err(Error::SyntaxError { detail: SyntaxError::Unexpected(UnexpectedKind::CloseDelimiter), .. }) =>
Ok(FullToken::End),
Err(e) => Err(e),
}
}
fn skip_annotations(&mut self) -> ReaderResult<Option<ValueClass>> {
loop {
match self.peek_class()? {
Some(NextToken::Annotation) => {
self.open_annotation()?;
self.skip_value()?;
self.close_annotation()?;
}
Some(NextToken::Value(v)) => return Ok(Some(v)),
Some(NextToken::End) => return Err(self.wrap_syntax_error(
SyntaxError::Unexpected(UnexpectedKind::CloseDelimiter))),
None => return Ok(None),
}
}
}
fn skip_value(&mut self) -> ReaderResult<()> {
match self.skip_annotations()?.ok_or_else(|| self.wrap_syntax_error(SyntaxError::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 b = B::start(B::Item::RecordLabel);
self.boundary(&b)?;
self.skip_value()?;
self.discard_until_complete(b, &B::Item::RecordField)
}
ValueClass::Compound(CompoundClass::Sequence) => {
self.open_sequence()?;
self.discard_until_complete(B::Type::default(), &B::Item::SequenceValue)
}
ValueClass::Compound(CompoundClass::Set) => {
self.open_set()?;
self.discard_until_complete(B::Type::default(), &B::Item::SetValue)
}
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 next_boolean(&mut self) -> ReaderResult<bool> { next_atom_expect(self) }
fn next_double(&mut self) -> ReaderResult<f64> { next_atom_expect(self) }
fn next_signedinteger(&mut self) -> ReaderResult<Cow<'de, SignedInteger>> { next_atom_expect(self) }
fn next_str(&mut self) -> ReaderResult<Cow<'de, str>> { next_atom_expect(self) }
fn next_bytestring(&mut self) -> ReaderResult<Cow<'de, [u8]>> { next_atom_expect(self) }
fn next_symbol(&mut self) -> ReaderResult<Cow<'de, str>> {
match self.next_atom()? {
Atom::Symbol(s) => Ok(s),
_ => Err(self.wrap_syntax_error(SyntaxError::Expected(ExpectedKind::Symbol))),
}
}
fn next_i8(&mut self) -> ReaderResult<i8> { check_out_of_range(self) }
fn next_u8(&mut self) -> ReaderResult<u8> { check_out_of_range(self) }
fn next_i16(&mut self) -> ReaderResult<i16> { check_out_of_range(self) }
fn next_u16(&mut self) -> ReaderResult<u16> { check_out_of_range(self) }
fn next_i32(&mut self) -> ReaderResult<i32> { check_out_of_range(self) }
fn next_u32(&mut self) -> ReaderResult<u32> { check_out_of_range(self) }
fn next_i64(&mut self) -> ReaderResult<i64> { check_out_of_range(self) }
fn next_u64(&mut self) -> ReaderResult<u64> { check_out_of_range(self) }
fn next_i128(&mut self) -> ReaderResult<i128> { check_out_of_range(self) }
fn next_u128(&mut self) -> ReaderResult<u128> { check_out_of_range(self) }
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(self.wrap_syntax_error(SyntaxError::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(self.wrap_syntax_error(SyntaxError::Expected(ExpectedKind::Value)))
}
}
fn ensure_complete(&mut self, mut b: B::Type, i: &B::Item) -> ReaderResult<()> {
if !self.close_compound(&mut b, i)? {
Err(self.wrap_syntax_error(SyntaxError::Expected(ExpectedKind::CloseDelimiter)))
} else {
Ok(())
}
}
fn discard_until_complete(&mut self, mut b: B::Type, i: &B::Item) -> ReaderResult<()> {
while !self.close_compound(&mut b, i)? {
self.skip_value()?;
}
Ok(())
}
fn specialized(&mut self) -> Option<(&str, &mut dyn BinarySource<'de>)> { None }
}
fn next_atom_expect<'de, R: Reader<'de> + ?Sized, T: TryFrom<Atom<'de>, Error = ExpectedKind>>(r: &mut R) -> ReaderResult<T> {
match r.next_atom()?.try_into() {
Ok(v) => Ok(v),
Err(k) => Err(r.wrap_syntax_error(SyntaxError::Expected(k))),
}
}
fn check_out_of_range<'de, R: Reader<'de> + ?Sized, T: for<'i> TryFrom<&'i SignedInteger, Error = OutOfRange>>(r: &mut R) -> ReaderResult<T> {
let i = r.next_signedinteger()?;
Ok(T::try_from(i.as_ref()).map_err(|e| r.wrap_syntax_error(SyntaxError::NumberOutOfRange(e.0)))?)
}
pub struct ValueStream<'de, 'dec, R: Reader<'de>, D: Domain, VR: ValueReader<D>, Dec: DomainDecode<D>> {
pub reader: R,
pub read_annotations: bool,
pub dec: &'dec mut Dec,
phantom: PhantomData<&'de (D, VR)>,
}
impl<'de, 'dec, R: Reader<'de>, D: Domain, VR: ValueReader<D>, Dec: DomainDecode<D>>
ValueStream<'de, 'dec, R, D, VR, Dec>
{
pub fn new(reader: R, dec: &'dec mut Dec) -> Self {
ValueStream {
reader,
read_annotations: true,
dec,
phantom: PhantomData,
}
}
pub fn read_annotations(mut self, read_annotations: bool) -> Self {
self.read_annotations = read_annotations;
self
}
pub fn read_all(&mut self) -> ReaderResult<Vec<Value<D>>> {
self.collect()
}
}
impl<'de, 'dec, R: Reader<'de>, D: Domain, VR: ValueReader<D>, Dec: DomainDecode<D>>
Iterator for ValueStream<'de, 'dec, R, D, VR, Dec>
{
type Item = ReaderResult<Value<D>>;
fn next(&mut self) -> Option<Self::Item> {
match self.reader.has_next() {
Err(e) => Some(Err(e)),
Ok(true) => Some(VR::read(&mut self.reader, self.read_annotations, self.dec)),
Ok(false) => None,
}
}
}
pub struct IOValueStream<'de, R: Reader<'de>, VR: IOValueReader> {
pub reader: R,
pub read_annotations: bool,
phantom: PhantomData<&'de VR>,
}
impl<'de, R: Reader<'de>, VR: IOValueReader> IOValueStream<'de, R, VR> {
pub fn new(reader: R) -> Self {
IOValueStream {
reader,
read_annotations: true,
phantom: PhantomData,
}
}
pub fn read_annotations(mut self, read_annotations: bool) -> Self {
self.read_annotations = read_annotations;
self
}
pub fn read_all(&mut self) -> ReaderResult<Vec<IOValue>> {
self.collect()
}
}
impl<'de, R: Reader<'de>, VR: IOValueReader> Iterator for IOValueStream<'de, R, VR> {
type Item = ReaderResult<IOValue>;
fn next(&mut self) -> Option<Self::Item> {
match self.reader.has_next() {
Err(e) => Some(Err(e)),
Ok(true) => Some(VR::read_iovalue(&mut self.reader, self.read_annotations)),
Ok(false) => None,
}
}
}