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)]
|
#[cfg(test)]
|
||||||
mod decoder_tests {
|
mod decoder_tests {
|
||||||
use crate::value::codec::Decoder;
|
use crate::value::codec::Decoder;
|
||||||
|
use crate::value::value::Value;
|
||||||
|
|
||||||
#[test] fn read_123() {
|
#[test] fn read_123() {
|
||||||
let mut d = Decoder::new(&b"abc"[..], None);
|
let mut d = Decoder::new(&b"abc"[..], None);
|
||||||
|
@ -185,8 +186,24 @@ mod decoder_tests {
|
||||||
assert!(d.read().err().unwrap().is_eof())
|
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() {
|
#[test] fn read_samples() {
|
||||||
let mut d = Decoder::new(std::fs::File::open("../../tests/samples.bin").unwrap(), None);
|
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,
|
index: usize,
|
||||||
buf: Box<Option<Option<u8>>>,
|
buf: Box<Option<Option<u8>>>,
|
||||||
placeholders: PlaceholderMap,
|
placeholders: PlaceholderMap,
|
||||||
|
read_annotations: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read> Decoder<R> {
|
impl<R: Read> Decoder<R> {
|
||||||
|
@ -45,11 +46,16 @@ impl<R: Read> Decoder<R> {
|
||||||
read,
|
read,
|
||||||
index: 0,
|
index: 0,
|
||||||
buf: Box::new(None),
|
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 {
|
match *self.buf {
|
||||||
None => {
|
None => {
|
||||||
let bs = &mut [0];
|
let bs = &mut [0];
|
||||||
|
@ -68,13 +74,13 @@ impl<R: Read> Decoder<R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn skip(&mut self) -> Result<()> {
|
pub fn skip(&mut self) -> Result<()> {
|
||||||
self.prime_if_possible()?;
|
self.prime()?;
|
||||||
*self.buf = None;
|
*self.buf = None;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn peek(&mut self) -> Result<u8> {
|
pub fn peek(&mut self) -> Result<u8> {
|
||||||
self.prime_if_possible()?;
|
self.prime()?;
|
||||||
match *self.buf {
|
match *self.buf {
|
||||||
Some(Some(v)) => Ok(v),
|
Some(Some(v)) => Ok(v),
|
||||||
Some(None) => Err(Error::Eof),
|
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>> {
|
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 {
|
while count > 0 {
|
||||||
pieces.push(self.next()?);
|
pieces.push(self.next()?);
|
||||||
count = count - 1;
|
count = count - 1;
|
||||||
|
@ -113,12 +119,15 @@ impl<R: Read> Decoder<R> {
|
||||||
Ok(pieces)
|
Ok(pieces)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nextop(&mut self) -> Result<(u8, u8, u8)> {
|
pub fn decodeop(b: u8) -> (u8, u8, u8) {
|
||||||
let b = self.read()?;
|
|
||||||
let major = b >> 6;
|
let major = b >> 6;
|
||||||
let minor = (b >> 4) & 3;
|
let minor = (b >> 4) & 3;
|
||||||
let arg = b & 15;
|
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> {
|
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())
|
Ok(Value::from(f64::from_bits(u64::from_be_bytes(bs.try_into().unwrap()))).wrap())
|
||||||
}
|
}
|
||||||
(0, 0, 5) => {
|
(0, 0, 5) => {
|
||||||
let a = self.next()?;
|
if self.read_annotations {
|
||||||
let mut v = self.next()?;
|
let mut annotations = vec![self.next()?];
|
||||||
v.annotations_mut().push(a);
|
while Self::decodeop(self.peek()?) == (0, 0, 5) {
|
||||||
Ok(v)
|
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, 0, _) => Err(Error::Syntax("Invalid format A encoding")),
|
||||||
(0, 1, arg) => {
|
(0, 1, arg) => {
|
||||||
|
|
|
@ -10,7 +10,7 @@ use std::ops::Index;
|
||||||
use std::ops::IndexMut;
|
use std::ops::IndexMut;
|
||||||
|
|
||||||
/// The `Value`s from the specification.
|
/// The `Value`s from the specification.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
pub enum Value {
|
pub enum Value {
|
||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
Float(Float),
|
Float(Float),
|
||||||
|
@ -27,7 +27,7 @@ pub enum Value {
|
||||||
|
|
||||||
/// An possibly-annotated Value, with annotations (themselves
|
/// An possibly-annotated Value, with annotations (themselves
|
||||||
/// possibly-annotated) in order of appearance.
|
/// possibly-annotated) in order of appearance.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone)]
|
||||||
pub struct AValue(pub Vec<AValue>, pub Value);
|
pub struct AValue(pub Vec<AValue>, pub Value);
|
||||||
|
|
||||||
/// Single-precision IEEE 754 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 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 {
|
impl AValue {
|
||||||
|
|
Loading…
Reference in New Issue