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

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)),
}
}
}
}
}