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

71 lines
2.5 KiB
Rust

use super::value::{Value, NestedValue, Domain, IOValue, UnwrappedIOValue, Float, Double};
use super::signed_integer::SignedIntegerRepr;
use super::writer::Writer;
pub use super::writer::Result;
pub struct Encoder<'a, W: Writer> {
pub write: &'a mut W,
}
pub fn encode_bytes(v: &IOValue) -> std::io::Result<Vec<u8>> {
let mut buf: Vec<u8> = Vec::new();
Encoder::new(&mut buf).write(v)?;
Ok(buf)
}
impl<'a, W: Writer> Encoder<'a, W> {
pub fn new(write: &'a mut W) -> Self {
Encoder { write }
}
pub fn write(&mut self, v: &IOValue) -> Result {
match v.annotations().maybe_slice() {
None => (),
Some(anns) => for ann in anns {
self.write.write_annotation_prefix()?;
self.write(ann)?;
}
}
self.write_value(v.value())
}
pub fn write_value(&mut self, v: &UnwrappedIOValue) -> Result {
match v {
Value::Boolean(b) => self.write.write_bool(*b),
Value::Float(Float(f)) => self.write.write_f32(*f),
Value::Double(Double(d)) => self.write.write_f64(*d),
Value::SignedInteger(n) => match n.repr() {
SignedIntegerRepr::I128(i) => self.write.write_i128(*i),
SignedIntegerRepr::U128(u) => self.write.write_u128(*u),
SignedIntegerRepr::Big(ref n) => self.write.write_int(n),
}
Value::String(ref s) => self.write.write_string(s),
Value::ByteString(ref bs) => self.write.write_bytes(bs),
Value::Symbol(ref s) => self.write.write_symbol(s),
Value::Record(r) => {
self.write.open_record(r.arity())?;
self.write(r.label())?;
for f in r.fields() { self.write(f)?; }
self.write.close_record()
}
Value::Sequence(ref vs) => {
self.write.open_sequence(vs.len())?;
for v in vs { self.write(v)?; }
self.write.close_sequence()
}
Value::Set(ref vs) => {
self.write.open_set(vs.len())?;
for v in vs { self.write(v)?; }
self.write.close_set()
}
Value::Dictionary(ref vs) => {
self.write.open_dictionary(vs.len())?;
for (k, v) in vs { self.write(k)?; self.write(v)?; }
self.write.close_dictionary()
}
Value::Domain(ref d) => self.write(&d.as_preserves()?)
}
}
}