This commit is contained in:
Tony Garnock-Jones 2022-11-03 21:12:15 +01:00
parent 1fc7b5b404
commit 66b37bd70a
10 changed files with 162 additions and 312 deletions

View File

@ -36,6 +36,7 @@ pub enum ExpectedKind {
Option,
UnicodeScalar,
Annotation,
}
impl From<io::Error> for Error {

View File

@ -2,14 +2,23 @@ pub mod boundary;
pub mod domain;
pub mod error;
pub mod float;
pub mod hex;
pub mod packed;
pub mod reader;
pub mod repr;
pub mod signed_integer;
pub mod source;
// pub mod text;
pub mod types;
pub mod writer;
pub use domain::*;
pub use packed::PackedReader;
pub use packed::PackedWriter;
pub use packed::annotated_from_bytes;
pub use packed::annotated_iovalue_from_bytes;
pub use packed::from_bytes;
pub use packed::iovalue_from_bytes;
pub use reader::Reader;
pub use repr::Annotations;
pub use repr::Atom;
@ -28,6 +37,12 @@ pub use signed_integer::SignedInteger;
pub use source::BinarySource;
pub use source::BytesBinarySource;
pub use source::IOBinarySource;
// pub use text::TextReader;
// pub use text::TextWriter;
// pub use text::annotated_from_str;
// pub use text::annotated_iovalue_from_str;
// pub use text::from_str;
// pub use text::iovalue_from_str;
pub use types::AtomClass;
pub use types::CompoundClass;
pub use types::ValueClass;

View File

@ -7,26 +7,32 @@ pub use writer::PackedWriter;
use std::io;
use super::{BinarySource, DomainDecode, IOValue, IOValueDomainCodec, NestedValue, Reader};
use crate::BinarySource;
use crate::BytesBinarySource;
use crate::Domain;
use crate::DomainDecode;
use crate::IOValue;
use crate::Reader;
use crate::Value;
pub fn from_bytes<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>>(
pub fn from_bytes<'de, D: Domain + 'static, Dec: DomainDecode<D>>(
bs: &'de [u8],
decode_embedded: &mut Dec,
) -> io::Result<N> {
super::BytesBinarySource::new(bs).packed().demand_next_domain(false, decode_embedded)
) -> io::Result<Box<dyn Value<D>>> {
BytesBinarySource::new(bs).packed().next(false, decode_embedded)
}
pub fn iovalue_from_bytes(bs: &[u8]) -> io::Result<IOValue> {
from_bytes(bs, &mut IOValueDomainCodec)
super::BytesBinarySource::new(bs).packed().next_iovalue(false)
}
pub fn annotated_from_bytes<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>>(
pub fn annotated_from_bytes<'de, D: Domain + 'static, Dec: DomainDecode<D>>(
bs: &'de [u8],
decode_embedded: &mut Dec,
) -> io::Result<N> {
super::BytesBinarySource::new(bs).packed().demand_next_domain(true, decode_embedded)
) -> io::Result<Box<dyn Value<D>>> {
super::BytesBinarySource::new(bs).packed().next(true, decode_embedded)
}
pub fn annotated_iovalue_from_bytes(bs: &[u8]) -> io::Result<IOValue> {
annotated_from_bytes(bs, &mut IOValueDomainCodec)
super::BytesBinarySource::new(bs).packed().next_iovalue(true)
}

View File

@ -1,5 +1,5 @@
use crate::{ValueClass, AtomClass, Atom};
use crate::error::{self, ExpectedKind, io_eof};
use crate::value::Domain;
use num::bigint::BigInt;
use num::traits::cast::{FromPrimitive, ToPrimitive};
@ -13,16 +13,11 @@ use std::marker::PhantomData;
use super::constants::Tag;
use super::super::{
CompoundClass,
DomainDecode,
Map,
NestedValue,
Record,
Set,
Value,
boundary as B,
reader::{
Token,
NextToken,
Reader,
ReaderResult,
},
@ -36,13 +31,12 @@ pub struct PackedReader<'de, 'src, S: BinarySource<'de>> {
}
impl<'de, 'src, S: BinarySource<'de>> BinarySource<'de> for PackedReader<'de, 'src, S> {
type Mark = S::Mark;
#[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> {
fn mark(&mut self) -> io::Result<usize> {
self.source.mark()
}
#[inline(always)]
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
fn restore(&mut self, mark: usize) -> io::Result<()> {
self.source.restore(mark)
}
#[inline(always)]
@ -257,38 +251,6 @@ impl<'de, 'src, S: BinarySource<'de>> PackedReader<'de, 'src, S> {
}
}
fn gather_annotations<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
dec: &mut Dec,
) -> io::Result<Vec<N>> {
let mut annotations = vec![self.demand_next_domain(true, dec)?];
while Tag::try_from(self.peek_noeof()?)? == Tag::Annotation {
self.skip()?;
annotations.push(self.demand_next_domain(true, dec)?);
}
Ok(annotations)
}
fn skip_annotations(&mut self) -> io::Result<()> {
self.skip_value()?;
while Tag::try_from(self.peek_noeof()?)? == Tag::Annotation {
self.skip()?;
self.skip_value()?;
}
Ok(())
}
fn next_upto_end<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
dec: &mut Dec,
) -> io::Result<Option<N>> {
match self.peekend()? {
true => Ok(None),
false => Ok(Some(self.demand_next_domain(read_annotations, dec)?)),
}
}
#[inline(always)]
fn decodestr<'a>(&mut self, cow: Cow<'a, [u8]>) -> io::Result<Cow<'a, str>> {
match cow {
@ -301,103 +263,72 @@ impl<'de, 'src, S: BinarySource<'de>> PackedReader<'de, 'src, S> {
}
impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, 'src, S> {
fn next_domain<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
dec: &mut Dec,
) -> io::Result<Option<N>> {
match self.peek()? {
fn peek_class(&mut self) -> io::Result<Option<NextToken>> {
match Tag::try_from(match self.peek()? {
None => return Ok(None),
Some(_) => (),
Some(b) => b,
})? {
Tag::False => Ok(Some(NextToken::Value(ValueClass::Atomic(AtomClass::Boolean)))),
Tag::True => Ok(Some(NextToken::Value(ValueClass::Atomic(AtomClass::Boolean)))),
Tag::Float => Ok(Some(NextToken::Value(ValueClass::Atomic(AtomClass::Float)))),
Tag::Double => Ok(Some(NextToken::Value(ValueClass::Atomic(AtomClass::Double)))),
Tag::Annotation => Ok(Some(NextToken::Annotation)),
Tag::Embedded => Ok(Some(NextToken::Value(ValueClass::Embedded))),
Tag::SmallInteger(_) => Ok(Some(NextToken::Value(ValueClass::Atomic(AtomClass::SignedInteger)))),
Tag::MediumInteger(_) => Ok(Some(NextToken::Value(ValueClass::Atomic(AtomClass::SignedInteger)))),
Tag::SignedInteger => Ok(Some(NextToken::Value(ValueClass::Atomic(AtomClass::SignedInteger)))),
Tag::String => Ok(Some(NextToken::Value(ValueClass::Atomic(AtomClass::String)))),
Tag::ByteString => Ok(Some(NextToken::Value(ValueClass::Atomic(AtomClass::ByteString)))),
Tag::Symbol => Ok(Some(NextToken::Value(ValueClass::Atomic(AtomClass::Symbol)))),
Tag::Record => Ok(Some(NextToken::Value(ValueClass::Compound(CompoundClass::Record)))),
Tag::Sequence => Ok(Some(NextToken::Value(ValueClass::Compound(CompoundClass::Sequence)))),
Tag::Set => Ok(Some(NextToken::Value(ValueClass::Compound(CompoundClass::Set)))),
Tag::Dictionary => Ok(Some(NextToken::Value(ValueClass::Compound(CompoundClass::Dictionary)))),
tag @ Tag::End => Err(self.syntax_error(&format!("Invalid tag: {:?}", tag))),
}
Ok(Some(match Tag::try_from(self.read()?)? {
Tag::False => N::new(false),
Tag::True => N::new(true),
}
fn next_atom(&mut self) -> ReaderResult<Atom<'de>> {
match Tag::try_from(self.read()?)? {
Tag::False => Ok(Atom::Boolean(false)),
Tag::True => Ok(Atom::Boolean(true)),
Tag::Float => {
let mut bs = [0; 4];
self.readbytes_into(&mut bs)?;
Value::from(f32::from_bits(u32::from_be_bytes(bs))).wrap()
Ok(Atom::Float(f32::from_bits(u32::from_be_bytes(bs))))
}
Tag::Double => {
let mut bs = [0; 8];
self.readbytes_into(&mut bs)?;
Value::from(f64::from_bits(u64::from_be_bytes(bs))).wrap()
}
Tag::Annotation => {
if read_annotations {
let mut annotations = self.gather_annotations(dec)?;
let (existing_annotations, v) = self.demand_next_domain::<N, _>(read_annotations, dec)?.pieces();
if let Some(vs) = existing_annotations {
annotations.extend_from_slice(&vs[..]);
}
N::wrap(Some(Box::new(annotations)), v)
} else {
self.skip_annotations()?;
self.demand_next_domain(read_annotations, dec)?
}
}
Tag::Embedded => {
Value::Embedded(dec.decode_embedded(self, read_annotations)?).wrap()
}
Tag::SmallInteger(v) => {
// TODO: prebuild these in value.rs
Value::from(v).wrap()
}
Tag::MediumInteger(count) => {
let n = self.read_signed_integer(count.into())?;
Value::SignedInteger(n).wrap()
Ok(Atom::Double(f64::from_bits(u64::from_be_bytes(bs))))
}
Tag::SmallInteger(v) => Ok(Atom::SignedInteger(v.into())),
Tag::MediumInteger(count) => Ok(Atom::SignedInteger(self.read_signed_integer(count.into())?)),
Tag::SignedInteger => {
let count = self.varint()?;
let n = self.read_signed_integer(count)?;
Value::SignedInteger(n).wrap()
Ok(Atom::SignedInteger(self.read_signed_integer(count)?))
}
Tag::String => {
let count = self.varint()?;
let bs = self.readbytes(count)?;
Value::String(self.decodestr(bs)?.into_owned()).wrap()
Ok(Atom::String(self.decodestr(bs)?))
}
Tag::ByteString => {
let count = self.varint()?;
Value::ByteString(self.readbytes(count)?.into_owned()).wrap()
Ok(Atom::ByteString(self.readbytes(count)?))
}
Tag::Symbol => {
let count = self.varint()?;
let bs = self.readbytes(count)?;
Value::Symbol(self.decodestr(bs)?.into_owned()).wrap()
Ok(Atom::Symbol(self.decodestr(bs)?))
}
Tag::Record => {
let mut vs = Vec::new();
while let Some(v) = self.next_upto_end(read_annotations, dec)? { vs.push(v); }
if vs.is_empty() {
return Err(self.syntax_error("Too few elements in encoded record"))
}
Value::Record(Record(vs)).wrap()
}
Tag::Sequence => {
let mut vs = Vec::new();
while let Some(v) = self.next_upto_end(read_annotations, dec)? { vs.push(v); }
Value::Sequence(vs).wrap()
}
Tag::Set => {
let mut s = Set::new();
while let Some(v) = self.next_upto_end(read_annotations, dec)? { s.insert(v); }
Value::Set(s).wrap()
}
Tag::Dictionary => {
let mut d = Map::new();
while let Some(k) = self.next_upto_end(read_annotations, dec)? {
match self.next_upto_end(read_annotations, dec)? {
Some(v) => { d.insert(k, v); }
None => return Err(self.syntax_error("Missing dictionary value")),
}
}
Value::Dictionary(d).wrap()
}
tag @ Tag::End => {
return Err(self.syntax_error(&format!("Invalid tag: {:?}", tag)));
}
}))
_ => Err(self.syntax_error("Expected atomic value"))?,
}
}
#[inline(always)]
fn boundary(&mut self, _b: &B::Type) -> ReaderResult<()> {
Ok(())
}
#[inline(always)]
@ -420,11 +351,6 @@ impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, 'src, S>
self.next_compound(Tag::Dictionary, ExpectedKind::Dictionary)
}
#[inline(always)]
fn boundary(&mut self, _b: &B::Type) -> ReaderResult<()> {
Ok(())
}
#[inline(always)]
fn close_compound(&mut self, _b: &mut B::Type, _i: &B::Item) -> ReaderResult<bool> {
Ok(self.peekend()?)
@ -440,57 +366,16 @@ impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, 'src, S>
Ok(())
}
type Mark = S::Mark;
#[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> {
fn mark(&mut self) -> io::Result<usize> {
self.source.mark()
}
#[inline(always)]
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
fn restore(&mut self, mark: usize) -> io::Result<()> {
self.source.restore(mark)
}
fn next_token<D: Domain, Dec: DomainDecode<D>>(
&mut self,
read_embedded_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Token<D>> {
loop {
return Ok(match Tag::try_from(self.peek_noeof()?)? {
Tag::Embedded => {
self.skip()?;
Token::Embedded(decode_embedded.decode_embedded(self, read_embedded_annotations)?)
}
Tag::False |
Tag::True |
Tag::Float |
Tag::Double |
Tag::SmallInteger(_) |
Tag::MediumInteger(_) |
Tag::SignedInteger |
Tag::String |
Tag::ByteString |
Tag::Symbol =>
Token::Atom(self.demand_next_domain(false, decode_embedded)?),
Tag::Record => { self.skip()?; Token::Compound(CompoundClass::Record) }
Tag::Sequence => { self.skip()?; Token::Compound(CompoundClass::Sequence) }
Tag::Set => { self.skip()?; Token::Compound(CompoundClass::Set) }
Tag::Dictionary => { self.skip()?; Token::Compound(CompoundClass::Dictionary) }
Tag::End => { self.skip()?; Token::End }
Tag::Annotation => {
self.skip()?;
self.skip_annotations()?;
continue
}
})
}
}
#[inline(always)]
fn next_boolean(&mut self) -> ReaderResult<bool> {
match self.peek_next_nonannotation_tag()? {
@ -532,7 +417,7 @@ impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, 'src, S>
fn next_u64(&mut self) -> ReaderResult<u64> { self.next_unsigned(|n| n.to_u64()) }
fn next_u128(&mut self) -> ReaderResult<u128> { self.next_unsigned(|n| n.to_u128()) }
fn next_f32(&mut self) -> ReaderResult<f32> {
fn next_float(&mut self) -> ReaderResult<f32> {
match self.peek_next_nonannotation_tag()? {
Tag::Float => {
self.skip()?;
@ -550,7 +435,7 @@ impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, 'src, S>
}
}
fn next_f64(&mut self) -> ReaderResult<f64> {
fn next_double(&mut self) -> ReaderResult<f64> {
match self.peek_next_nonannotation_tag()? {
Tag::Float => {
self.skip()?;
@ -581,4 +466,12 @@ impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, 'src, S>
let bs = self.next_atomic(Tag::Symbol, ExpectedKind::Symbol)?;
Ok(self.decodestr(bs)?)
}
fn open_annotation(&mut self) -> ReaderResult<()> {
self.next_compound(Tag::Annotation, ExpectedKind::Annotation)
}
fn close_annotation(&mut self) -> ReaderResult<()> {
Ok(())
}
}

View File

@ -4,12 +4,7 @@ use std::convert::TryInto;
use std::io;
use std::io::Write;
use super::constants::Tag;
use super::super::DomainEncode;
use super::super::IOValue;
use super::super::IOValueDomainCodec;
use super::super::NestedValue;
use super::super::boundary as B;
use super::super::writer::Writer;
use crate::{boundary as B, Value, Domain, DomainEncode, IOValue, IOValueDomainCodec, Writer};
struct Buffers<W: io::Write> {
base: W,
@ -41,12 +36,12 @@ pub struct PackedWriter<W: io::Write>(Buffers<W>);
impl PackedWriter<&mut Vec<u8>> {
#[inline(always)]
pub fn encode<N: NestedValue, Enc: DomainEncode<N::Embedded>>(
pub fn encode<D: Domain, Enc: DomainEncode<D>>(
enc: &mut Enc,
v: &N,
v: &dyn Value<D>,
) -> io::Result<Vec<u8>> {
let mut buf: Vec<u8> = Vec::new();
PackedWriter::new(&mut buf).write(enc, v)?;
v.write(&mut PackedWriter::new(&mut buf), enc)?;
Ok(buf)
}

View File

@ -1,6 +1,7 @@
use std::borrow::Cow;
use std::convert::TryFrom;
use std::io;
use std::marker::PhantomData;
use crate::CompoundClass;
use crate::SignedInteger;
@ -286,6 +287,7 @@ pub trait Reader<'de> {
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> {
@ -293,6 +295,7 @@ impl<'de, R: Reader<'de>> IOValues<'de, R> {
IOValues {
reader,
read_annotations: false,
phantom: PhantomData,
}
}

View File

@ -4,9 +4,8 @@ use std::borrow::Cow;
use std::io;
pub trait BinarySource<'de>: Sized {
type Mark;
fn mark(&mut self) -> io::Result<Self::Mark>;
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()>;
fn mark(&mut self) -> io::Result<usize>;
fn restore(&mut self, mark: usize) -> io::Result<()>;
fn input_position(&mut self) -> io::Result<Option<usize>>;
fn skip(&mut self) -> io::Result<()>;
@ -27,6 +26,14 @@ pub trait BinarySource<'de>: Sized {
message: message.to_owned(),
})
}
fn packed(&mut self) -> super::PackedReader<'de, '_, Self> {
super::PackedReader::new(self)
}
// fn text(&mut self) -> super::TextReader<'de, '_, Self> {
// super::TextReader::new(self)
// }
}
#[derive(Debug)]
@ -61,16 +68,15 @@ impl<R: io::Read + io::Seek> IOBinarySource<R> {
}
impl<'de, R: io::Read + io::Seek> BinarySource<'de> for IOBinarySource<R> {
type Mark = u64;
#[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> {
Ok(self.read.stream_position()? - (if self.buf.is_some() { 1 } else { 0 }))
fn mark(&mut self) -> io::Result<usize> {
let pos = self.read.stream_position()? - (if self.buf.is_some() { 1 } else { 0 });
Ok(pos as usize)
}
#[inline(always)]
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
self.read.seek(io::SeekFrom::Start(*mark))?;
fn restore(&mut self, mark: usize) -> io::Result<()> {
self.read.seek(io::SeekFrom::Start(mark as u64))?;
self.buf = None;
Ok(())
}
@ -146,16 +152,14 @@ impl<'de> BytesBinarySource<'de> {
}
impl<'de> BinarySource<'de> for BytesBinarySource<'de> {
type Mark = u64;
#[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> {
Ok(self.index)
fn mark(&mut self) -> io::Result<usize> {
Ok(self.index as usize)
}
#[inline(always)]
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
self.index = *mark;
fn restore(&mut self, mark: usize) -> io::Result<()> {
self.index = mark as u64;
Ok(())
}

View File

@ -1,33 +1,36 @@
use std::io;
pub mod reader;
pub mod writer;
pub use reader::TextReader;
pub use writer::TextWriter;
use crate::value::source::BytesBinarySource;
use crate::BytesBinarySource;
use crate::Domain;
use crate::DomainDecode;
use crate::IOValue;
use crate::Reader;
use crate::Value;
use std::io;
use super::{IOValue, IOValueDomainCodec, NestedValue, Reader, DomainDecode};
pub fn from_str<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>>(
pub fn from_str<'de, D: Domain + 'static, Dec: DomainDecode<D>>(
s: &'de str,
decode_embedded: &mut Dec,
) -> io::Result<N> {
TextReader::new(&mut BytesBinarySource::new(s.as_bytes())).demand_next_domain(false, decode_embedded)
) -> io::Result<Box<dyn Value<D>>> {
BytesBinarySource::new(s.as_bytes()).text().next(false, decode_embedded)
}
pub fn iovalue_from_str(s: &str) -> io::Result<IOValue> {
from_str(s, &mut IOValueDomainCodec)
BytesBinarySource::new(s.as_bytes()).text().next_iovalue(false)
}
pub fn annotated_from_str<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>>(
pub fn annotated_from_str<'de, D: Domain + 'static, Dec: DomainDecode<D>>(
s: &'de str,
decode_embedded: &mut Dec,
) -> io::Result<N> {
TextReader::new(&mut BytesBinarySource::new(s.as_bytes())).demand_next_domain(true, decode_embedded)
) -> io::Result<Box<dyn Value<D>>> {
BytesBinarySource::new(s.as_bytes()).text().next(true, decode_embedded)
}
pub fn annotated_iovalue_from_str(s: &str) -> io::Result<IOValue> {
annotated_from_str(s, &mut IOValueDomainCodec)
BytesBinarySource::new(s.as_bytes()).text().next_iovalue(true)
}

View File

@ -1,22 +1,21 @@
use crate::Atom;
use crate::error::Error;
use crate::error::ExpectedKind;
use crate::error::io_eof;
use crate::hex;
use crate::value::CompoundClass;
use crate::value::Domain;
use crate::value::DomainDecode;
use crate::value::Map;
use crate::value::NestedValue;
use crate::value::Reader;
use crate::value::Record;
use crate::value::Set;
use crate::value::Token;
use crate::value::Value;
use crate::value::boundary as B;
use crate::value::reader::ReaderResult;
use crate::value::source::BinarySource;
use crate::CompoundClass;
use crate::Domain;
use crate::DomainDecode;
use crate::Map;
use crate::Reader;
use crate::Record;
use crate::Set;
use crate::Value;
use crate::boundary as B;
use crate::reader::ReaderResult;
use crate::source::BinarySource;
use num::bigint::BigInt;
@ -74,32 +73,6 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
}
}
fn gather_annotations<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
decode_embedded: &mut Dec,
) -> ReaderResult<Vec<N>> {
let mut vs = Vec::new();
loop {
self.skip_whitespace();
match self.peek_noeof()? {
b';' => { self.skip()?; vs.push(N::new(self.comment_line()?)) }
b'@' => { self.skip()?; vs.push(self.demand_next_domain(true, decode_embedded)?) }
_ => return Ok(vs),
}
}
}
fn skip_annotations(&mut self) -> ReaderResult<()> {
loop {
self.skip_whitespace();
match self.peek_noeof()? {
b';' => { self.skip()?; self.comment_line()?; },
b'@' => { self.skip()?; self.skip_value()?; },
_ => return Ok(()),
}
}
}
fn decode_utf8(&mut self, bs: Vec<u8>) -> io::Result<String> {
String::from_utf8(bs).map_err(|_| self.syntax_error("Invalid UTF-8"))
}
@ -116,7 +89,7 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
}
}
fn read_intpart<N: NestedValue>(&mut self, mut bs: Vec<u8>, c: u8) -> io::Result<N> {
fn read_intpart(&mut self, mut bs: Vec<u8>, c: u8) -> io::Result<Atom<'de>> {
match c {
b'0' => {
bs.push(c);
@ -129,7 +102,7 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
}
}
fn read_fracexp<N: NestedValue>(&mut self, mut bs: Vec<u8>) -> io::Result<N> {
fn read_fracexp(&mut self, mut bs: Vec<u8>) -> io::Result<Atom<'de>> {
let mut is_float = false;
match self.peek_noeof() {
Ok(b'.') => {
@ -149,7 +122,7 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
}
}
fn read_sign_and_exp<N: NestedValue>(&mut self, mut bs: Vec<u8>) -> io::Result<N> {
fn read_sign_and_exp(&mut self, mut bs: Vec<u8>) -> io::Result<Atom<'de>> {
match self.peek_noeof()? {
b'+' | b'-' => bs.push(self.next_byte()?),
_ => (),
@ -159,23 +132,23 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
self.finish_number(bs, true)
}
fn finish_number<N: NestedValue>(&mut self, bs: Vec<u8>, is_float: bool) -> io::Result<N> {
fn finish_number(&mut self, bs: Vec<u8>, is_float: bool) -> io::Result<Atom<'de>> {
let s = self.decode_utf8(bs)?;
if is_float {
match self.peek_noeof() {
Ok(b'f') | Ok(b'F') => {
self.skip()?;
Ok(N::new(s.parse::<f32>().map_err(
Ok(Atom::Float(s.parse::<f32>().map_err(
|_| self.syntax_error(&format!(
"Invalid single-precision number: {:?}", s)))?))
}
_ =>
Ok(N::new(s.parse::<f64>().map_err(
Ok(Atom::Double(s.parse::<f64>().map_err(
|_| self.syntax_error(&format!(
"Invalid double-precision number: {:?}", s)))?))
}
} else {
Ok(N::new(s.parse::<BigInt>().map_err(
Ok(Atom::SignedInteger(s.parse::<BigInt>().map_err(
|_| self.syntax_error(&format!(
"Invalid signed-integer number: {:?}", s)))?))
}
@ -278,8 +251,8 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
self.decode_utf8(raw)
}
fn read_literal_binary<N: NestedValue>(&mut self) -> io::Result<N> {
Ok(N::new(&self.read_stringlike(
fn read_literal_binary(&mut self) -> io::Result<Atom<'de>> {
Ok(Atom::Bytes(&self.read_stringlike(
Vec::new(),
|_r, bs, b| Ok(bs.push(b)),
b'"',
@ -287,14 +260,14 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
|r, bs| Ok(bs.push(r.hexnum(2)? as u8)))?[..]))
}
fn read_hex_binary<N: NestedValue>(&mut self) -> io::Result<N> {
fn read_hex_binary(&mut self) -> io::Result<Atom<'de>> {
let mut s = String::new();
loop {
self.skip_whitespace();
let c1 = self.next_byte()? as char;
if c1 == '"' {
let bs = hex::HexParser::Strict.decode(&s).unwrap();
return Ok(N::new(&bs[..]));
return Ok(Atom::Bytes(&bs[..]));
}
let c2 = self.next_byte()? as char;
if !(c1.is_digit(16) && c2.is_digit(16)) {
@ -305,7 +278,7 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
}
}
fn read_base64_binary<N: NestedValue>(&mut self) -> io::Result<N> {
fn read_base64_binary(&mut self) -> io::Result<Atom<'de>> {
let mut bs = Vec::new();
loop {
self.skip_whitespace();
@ -313,7 +286,7 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
if c == b']' {
let bs = base64::decode_config(&self.decode_utf8(bs)?, base64::STANDARD_NO_PAD)
.map_err(|_| self.syntax_error("Invalid base64 character"))?;
return Ok(N::new(&bs[..]));
return Ok(Atom::Bytes(&bs[..]));
}
if c == b'-' { c = b'+'; }
if c == b'_' { c = b'/'; }
@ -322,46 +295,7 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
}
}
fn upto<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
delimiter: u8,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Vec<N>> {
let mut vs = Vec::new();
loop {
self.skip_whitespace();
if self.peek()? == Some(delimiter) {
self.skip()?;
return Ok(vs);
}
vs.push(self.demand_next_domain(read_annotations, decode_embedded)?);
}
}
fn read_dictionary<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<N> {
let mut d = Map::new();
loop {
self.skip_whitespace();
if self.peek_noeof()? == b'}' {
self.skip()?;
return Ok(N::new(d));
}
let k = self.demand_next_domain(read_annotations, decode_embedded)?;
self.skip_whitespace();
if self.next_byte()? != b':' {
return Err(self.syntax_error("Missing expected key/value separator"));
}
let v = self.demand_next_domain(read_annotations, decode_embedded)?;
d.insert(k, v);
}
}
fn read_raw_symbol<N: NestedValue>(&mut self, mut bs: Vec<u8>) -> io::Result<N> {
fn read_raw_symbol(&mut self, mut bs: Vec<u8>) -> io::Result<Atom<'de>> {
loop {
let c = match self.peek()? {
None => b' ',
@ -371,7 +305,7 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
match c {
b'(' | b')' | b'{' | b'}' | b'[' | b']' | b'<' | b'>' |
b'"' | b';' | b',' | b'@' | b'#' | b':' | b'|' | b' ' =>
return Ok(N::symbol(&self.decode_utf8(bs)?)),
return Ok(Atom::Symbol(&self.decode_utf8(bs)?)),
c => {
self.skip()?;
bs.push(c)
@ -383,17 +317,13 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for TextReader<'de, 'src, S>
{
fn next_domain<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Option<N>> {
fn peek_class(&mut self) -> io::Result<Option<crate::reader::NextToken>> {
self.skip_whitespace();
let c = match self.peek()? {
None => return Ok(None),
Some(c) => c,
};
Ok(Some(match c {
XX Ok(Some(match c {
b'-' => {
self.skip()?;
let c1 = self.next_byte()?;

View File

@ -6,6 +6,8 @@ use crate::boundary as B;
use crate::signed_integer::SignedIntegerRepr;
pub trait Writer {
fn boundary(&mut self, b: &B::Type) -> io::Result<()>;
fn start_annotations(&mut self) -> io::Result<()>;
fn end_annotations(&mut self) -> io::Result<()>;
@ -22,8 +24,6 @@ pub trait Writer {
fn write_bytes(&mut self, v: &[u8]) -> io::Result<()>;
fn write_symbol(&mut self, v: &str) -> io::Result<()>;
fn boundary(&mut self, b: &B::Type) -> io::Result<()>;
fn start_record(&mut self) -> io::Result<()>;
fn end_record(&mut self) -> io::Result<()>;