90 lines
3.4 KiB
Rust
90 lines
3.4 KiB
Rust
use super::value::{Value, NestedValue, Domain, IOValue, UnwrappedIOValue, Float, Double};
|
|
use super::signed_integer::SignedIntegerRepr;
|
|
use super::writer::Writer;
|
|
use super::packed::PackedWriter;
|
|
|
|
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 PackedWriter(&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<W::Pointer> {
|
|
match v.annotations().maybe_slice() {
|
|
None => self.write_value(v.value()),
|
|
Some(anns) => {
|
|
let mut a = self.write.start_annotation()?;
|
|
for ann in anns {
|
|
self.write.extend_annotation(&mut a, ann)?;
|
|
}
|
|
let p = self.write_value(v.value())?;
|
|
self.write.end_annotation(a, p)
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn write_value(&mut self, v: &UnwrappedIOValue) -> Result<W::Pointer> {
|
|
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) => {
|
|
let mut c = self.write.start_record(r.arity() as u64)?;
|
|
let p = self.write(r.label())?;
|
|
self.write.extend_compound(&mut c, p)?;
|
|
for f in r.fields() {
|
|
let p = self.write(f)?;
|
|
self.write.extend_compound(&mut c, p)?;
|
|
}
|
|
self.write.end_compound(c)
|
|
}
|
|
Value::Sequence(ref vs) => {
|
|
let mut c = self.write.start_sequence(vs.len() as u64)?;
|
|
for v in vs {
|
|
let p = self.write(v)?;
|
|
self.write.extend_compound(&mut c, p)?;
|
|
}
|
|
self.write.end_compound(c)
|
|
}
|
|
Value::Set(ref vs) => {
|
|
let mut c = self.write.start_set(vs.len() as u64)?;
|
|
for v in vs {
|
|
let p = self.write(v)?;
|
|
self.write.extend_compound(&mut c, p)?;
|
|
}
|
|
self.write.end_compound(c)
|
|
}
|
|
Value::Dictionary(ref vs) => {
|
|
let mut d = self.write.start_dictionary(vs.len() as u64)?;
|
|
for (k, v) in vs {
|
|
let p = self.write(k)?;
|
|
let kp = self.write.extend_dictionary_key(&mut d, p)?;
|
|
let p = self.write(v)?;
|
|
self.write.extend_dictionary_value(&mut d, kp, p)?;
|
|
}
|
|
self.write.end_dictionary(d)
|
|
}
|
|
Value::Domain(ref d) => self.write(&d.as_preserves()?)
|
|
}
|
|
}
|
|
}
|