171 lines
6.3 KiB
Rust
171 lines
6.3 KiB
Rust
use bytes::BytesMut;
|
|
use super::reader::{Reader, Token, err, is_eof_error, decodebinary};
|
|
use super::value::{Value, NestedValue, Set, Map, Domain};
|
|
use super::constants::{AtomMinor, CompoundMinor};
|
|
|
|
pub use super::reader::{Error, Result};
|
|
|
|
pub type DecodePlaceholderMap<N, D> = Map<usize, Value<N, D>>;
|
|
|
|
pub struct Decoder<'a, R: Reader, N: NestedValue<D>, D: Domain> {
|
|
pub read: R,
|
|
placeholders: Option<&'a DecodePlaceholderMap<N, D>>,
|
|
read_annotations: bool,
|
|
}
|
|
|
|
impl<'a, R: Reader, N: NestedValue<D>, D: Domain> Decoder<'a, R, N, D> {
|
|
pub fn new(read: R, placeholders: Option<&'a DecodePlaceholderMap<N, D>>) ->
|
|
Self
|
|
{
|
|
Decoder{
|
|
read,
|
|
placeholders,
|
|
read_annotations: true,
|
|
}
|
|
}
|
|
|
|
pub fn set_read_annotations(&mut self, read_annotations: bool) {
|
|
self.read_annotations = read_annotations
|
|
}
|
|
|
|
pub fn next_or_err(&mut self) -> Result<N> {
|
|
let t = self.read.next_token()?;
|
|
self.next_inner(t)
|
|
}
|
|
|
|
pub fn next_inner(&mut self, mut token: Token) -> Result<N> {
|
|
loop {
|
|
return match token {
|
|
Token::Annotation =>
|
|
if self.read_annotations {
|
|
let mut annotations = vec![self.next_or_err()?];
|
|
loop {
|
|
match self.read.next_token()? {
|
|
Token::Annotation =>
|
|
annotations.push(self.next_or_err()?),
|
|
other => {
|
|
token = other;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
let v = self.next_inner(token)?;
|
|
assert!(v.annotations().is_empty());
|
|
Ok(N::wrap_ann(annotations, v.value_owned()))
|
|
} else {
|
|
self.next_or_err()?;
|
|
token = self.read.next_token()?;
|
|
continue;
|
|
}
|
|
Token::PlaceholderRef(n) =>
|
|
match self.placeholders.and_then(|m| m.get(&n)) {
|
|
Some(v) => Ok(v.clone().wrap()),
|
|
None => Err(err("Invalid Preserves placeholder")),
|
|
}
|
|
Token::Noop => {
|
|
token = self.read.next_token()?;
|
|
continue;
|
|
}
|
|
|
|
Token::Boolean(b) => Ok(Value::from(b).wrap()),
|
|
Token::Float(f) => Ok(Value::from(f).wrap()),
|
|
Token::Double(d) => Ok(Value::from(d).wrap()),
|
|
Token::SignedInteger(i) => Ok(Value::from(i).wrap()),
|
|
Token::String(s) => Ok(Value::from(s).wrap()),
|
|
Token::ByteString(bs) => Ok(Value::ByteString(bs.to_vec()).wrap()),
|
|
Token::Symbol(s) => Ok(Value::symbol(&s).wrap()),
|
|
|
|
Token::OpenAtom(minor) => self.binarystream(minor),
|
|
Token::CloseAtom(minor) => Err(err(&format!("Unexpected {:?} close", minor))),
|
|
|
|
Token::OpenCompound(paren, mut limit) => self.decodecompound(paren, &mut limit),
|
|
Token::CloseCompound(paren) => Err(err(&format!("Unexpected {:?} close", paren))),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn binarystream(&mut self, minor: AtomMinor) -> Result<N> {
|
|
let mut bs = BytesMut::with_capacity(256);
|
|
while !self.read.at_atom_end(minor)? {
|
|
match self.next_or_err()?.value().as_bytestring() {
|
|
Some(chunk) => bs.extend_from_slice(chunk),
|
|
None => return Err(err("Unexpected non-binary chunk")),
|
|
}
|
|
}
|
|
// We know it'll be a SignedInteger, String, ByteString, or
|
|
// Symbol, so the recursion is safe.
|
|
self.next_inner(decodebinary(minor, bs)?)
|
|
}
|
|
|
|
pub fn decodecompound(&mut self, paren: CompoundMinor, limit: &mut Option<usize>) ->
|
|
Result<N>
|
|
{
|
|
match paren {
|
|
CompoundMinor::Record =>
|
|
match I(self, paren, limit).next() {
|
|
None => Err(err("Too few elements in encoded record")),
|
|
Some(labelres) => {
|
|
let label = labelres?;
|
|
Ok(Value::record(label, I(self, paren, limit).collect::<Result<Vec<N>>>()?).wrap())
|
|
}
|
|
}
|
|
CompoundMinor::Sequence => {
|
|
Ok(Value::Sequence(I(self, paren, limit).collect::<Result<Vec<N>>>()?).wrap())
|
|
}
|
|
CompoundMinor::Set => {
|
|
let mut s = Set::new();
|
|
for res in I(self, paren, limit) { s.insert(res?); }
|
|
Ok(Value::Set(s).wrap())
|
|
}
|
|
CompoundMinor::Dictionary => {
|
|
let mut d = Map::new();
|
|
while let Some(kres) = I(self, paren, limit).next() {
|
|
let k = kres?;
|
|
match I(self, paren, limit).next() {
|
|
Some(vres) => { d.insert(k, vres?); }
|
|
None => return Err(err("Missing dictionary value")),
|
|
}
|
|
}
|
|
Ok(Value::Dictionary(d).wrap())
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a, R: Reader, N: NestedValue<D>, D: Domain> std::iter::Iterator for Decoder<'a, R, N, D> {
|
|
type Item = Result<N>;
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
match self.next_or_err() {
|
|
Err(e) if is_eof_error(&e) => None,
|
|
other => Some(other)
|
|
}
|
|
}
|
|
}
|
|
|
|
struct I<'f, 'a, R: Reader, N: NestedValue<D>, D: Domain>(
|
|
&'f mut Decoder<'a, R, N, D>,
|
|
CompoundMinor,
|
|
&'f mut Option<usize>,
|
|
);
|
|
|
|
impl<'f, 'a, R: Reader, N: NestedValue<D>, D: Domain> Iterator for I<'f, 'a, R, N, D> {
|
|
type Item = Result<N>;
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
let I(d, paren, count) = self;
|
|
match count {
|
|
Some(0) => None,
|
|
Some(n) => {
|
|
*self.2 = Some(*n - 1);
|
|
Some(d.next_or_err())
|
|
},
|
|
None => {
|
|
match d.read.at_compound_end(*paren) {
|
|
Ok(true) => None,
|
|
Ok(false) => Some(d.next_or_err()),
|
|
Err(e) => Some(Err(e)),
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|