Annotation skipping; text-syntax-like debug printing (plus pretty printing for free!!)
This commit is contained in:
parent
365e41b798
commit
bec3a10d64
|
@ -176,6 +176,7 @@ mod value_tests {
|
|||
#[cfg(test)]
|
||||
mod decoder_tests {
|
||||
use crate::value::codec::Decoder;
|
||||
use crate::value::value::Value;
|
||||
|
||||
#[test] fn read_123() {
|
||||
let mut d = Decoder::new(&b"abc"[..], None);
|
||||
|
@ -185,8 +186,24 @@ mod decoder_tests {
|
|||
assert!(d.read().err().unwrap().is_eof())
|
||||
}
|
||||
|
||||
#[test] fn skip_annotations_noskip() {
|
||||
let mut d = Decoder::new(&b"\x0521"[..], None);
|
||||
let v = d.next().ok().unwrap();
|
||||
assert_eq!(v.annotations().len(), 1);
|
||||
assert_eq!(v.annotations()[0], Value::from(2).wrap());
|
||||
assert_eq!(v.value(), &Value::from(1));
|
||||
}
|
||||
|
||||
#[test] fn skip_annotations_skip() {
|
||||
let mut d = Decoder::new(&b"\x0521"[..], None);
|
||||
d.set_read_annotations(false);
|
||||
let v = d.next().ok().unwrap();
|
||||
assert_eq!(v.annotations().len(), 0);
|
||||
assert_eq!(v.value(), &Value::from(1));
|
||||
}
|
||||
|
||||
#[test] fn read_samples() {
|
||||
let mut d = Decoder::new(std::fs::File::open("../../tests/samples.bin").unwrap(), None);
|
||||
println!("{:?}", d.next().ok().unwrap());
|
||||
println!("{:#?}", d.next().ok().unwrap());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ pub struct Decoder<R: Read> {
|
|||
index: usize,
|
||||
buf: Box<Option<Option<u8>>>,
|
||||
placeholders: PlaceholderMap,
|
||||
read_annotations: bool,
|
||||
}
|
||||
|
||||
impl<R: Read> Decoder<R> {
|
||||
|
@ -45,11 +46,16 @@ impl<R: Read> Decoder<R> {
|
|||
read,
|
||||
index: 0,
|
||||
buf: Box::new(None),
|
||||
placeholders: placeholders.unwrap_or(PlaceholderMap::new())
|
||||
placeholders: placeholders.unwrap_or(PlaceholderMap::new()),
|
||||
read_annotations: true,
|
||||
}
|
||||
}
|
||||
|
||||
fn prime_if_possible(&mut self) -> Result<()> {
|
||||
pub fn set_read_annotations(&mut self, read_annotations: bool) -> () {
|
||||
self.read_annotations = read_annotations
|
||||
}
|
||||
|
||||
fn prime(&mut self) -> Result<()> {
|
||||
match *self.buf {
|
||||
None => {
|
||||
let bs = &mut [0];
|
||||
|
@ -68,13 +74,13 @@ impl<R: Read> Decoder<R> {
|
|||
}
|
||||
|
||||
pub fn skip(&mut self) -> Result<()> {
|
||||
self.prime_if_possible()?;
|
||||
self.prime()?;
|
||||
*self.buf = None;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn peek(&mut self) -> Result<u8> {
|
||||
self.prime_if_possible()?;
|
||||
self.prime()?;
|
||||
match *self.buf {
|
||||
Some(Some(v)) => Ok(v),
|
||||
Some(None) => Err(Error::Eof),
|
||||
|
@ -105,7 +111,7 @@ impl<R: Read> Decoder<R> {
|
|||
}
|
||||
|
||||
pub fn readvalues(&mut self, mut count: usize) -> Result<Vec<AValue>> {
|
||||
let mut pieces: Vec<AValue> = Vec::new();
|
||||
let mut pieces: Vec<AValue> = Vec::with_capacity(count);
|
||||
while count > 0 {
|
||||
pieces.push(self.next()?);
|
||||
count = count - 1;
|
||||
|
@ -113,12 +119,15 @@ impl<R: Read> Decoder<R> {
|
|||
Ok(pieces)
|
||||
}
|
||||
|
||||
pub fn nextop(&mut self) -> Result<(u8, u8, u8)> {
|
||||
let b = self.read()?;
|
||||
pub fn decodeop(b: u8) -> (u8, u8, u8) {
|
||||
let major = b >> 6;
|
||||
let minor = (b >> 4) & 3;
|
||||
let arg = b & 15;
|
||||
Ok((major, minor, arg))
|
||||
(major, minor, arg)
|
||||
}
|
||||
|
||||
pub fn nextop(&mut self) -> Result<(u8, u8, u8)> {
|
||||
Ok(Self::decodeop(self.read()?))
|
||||
}
|
||||
|
||||
pub fn varint(&mut self) -> Result<usize> {
|
||||
|
@ -225,10 +234,19 @@ impl<R: Read> Decoder<R> {
|
|||
Ok(Value::from(f64::from_bits(u64::from_be_bytes(bs.try_into().unwrap()))).wrap())
|
||||
}
|
||||
(0, 0, 5) => {
|
||||
let a = self.next()?;
|
||||
let mut v = self.next()?;
|
||||
v.annotations_mut().push(a);
|
||||
Ok(v)
|
||||
if self.read_annotations {
|
||||
let mut annotations = vec![self.next()?];
|
||||
while Self::decodeop(self.peek()?) == (0, 0, 5) {
|
||||
self.skip()?;
|
||||
annotations.push(self.next()?);
|
||||
}
|
||||
let mut v = self.next()?;
|
||||
v.annotations_mut().extend(annotations);
|
||||
Ok(v)
|
||||
} else {
|
||||
self.next()?;
|
||||
self.next()
|
||||
}
|
||||
}
|
||||
(0, 0, _) => Err(Error::Syntax("Invalid format A encoding")),
|
||||
(0, 1, arg) => {
|
||||
|
|
|
@ -10,7 +10,7 @@ use std::ops::Index;
|
|||
use std::ops::IndexMut;
|
||||
|
||||
/// The `Value`s from the specification.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub enum Value {
|
||||
Boolean(bool),
|
||||
Float(Float),
|
||||
|
@ -27,7 +27,7 @@ pub enum Value {
|
|||
|
||||
/// An possibly-annotated Value, with annotations (themselves
|
||||
/// possibly-annotated) in order of appearance.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone)]
|
||||
pub struct AValue(pub Vec<AValue>, pub Value);
|
||||
|
||||
/// Single-precision IEEE 754 Value
|
||||
|
@ -180,6 +180,58 @@ impl From<Vec<u8>> for Value { fn from(v: Vec<u8>) -> Self { Value::ByteString(v
|
|||
|
||||
impl From<Vec<AValue>> for Value { fn from(v: Vec<AValue>) -> Self { Value::Sequence(v) } }
|
||||
|
||||
impl std::fmt::Debug for Value {
|
||||
// Not *quite* a formatter for the Preserves text syntax, since it
|
||||
// doesn't escape strings/symbols properly.
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Value::Boolean(true) => f.write_str("#true"),
|
||||
Value::Boolean(false) => f.write_str("#false"),
|
||||
Value::Float(Float(v)) => write!(f, "{:?}f", v),
|
||||
Value::Double(Double(v)) => write!(f, "{:?}", v),
|
||||
Value::SignedInteger(v) => write!(f, "{}", v),
|
||||
Value::String(ref v) => write!(f, "{:?}", v), // TODO: proper escaping!
|
||||
Value::ByteString(ref v) => {
|
||||
f.write_str("#hex{")?;
|
||||
for b in v { write!(f, "{:02x}", b)? }
|
||||
f.write_str("}")
|
||||
}
|
||||
Value::Symbol(ref v) => {
|
||||
// TODO: proper escaping!
|
||||
if v.len() == 0 {
|
||||
f.write_str("||")
|
||||
} else {
|
||||
write!(f, "{}", v)
|
||||
}
|
||||
}
|
||||
Value::Record((ref l, ref fs)) => {
|
||||
f.write_str("<")?;
|
||||
l.fmt(f)?;
|
||||
for v in fs {
|
||||
f.write_str(" ")?;
|
||||
v.fmt(f)?;
|
||||
}
|
||||
f.write_str(">")
|
||||
}
|
||||
Value::Sequence(ref v) => v.fmt(f),
|
||||
Value::Set(ref v) => {
|
||||
f.write_str("#set")?;
|
||||
f.debug_set().entries(v.iter()).finish()
|
||||
}
|
||||
Value::Dictionary (ref v) => f.debug_map().entries(v.iter()).finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for AValue {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
for ann in &self.0 {
|
||||
write!(f, "@{:?} ", ann)?;
|
||||
}
|
||||
self.1.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
impl AValue {
|
||||
|
|
Loading…
Reference in New Issue