63 lines
2.4 KiB
Rust
63 lines
2.4 KiB
Rust
use super::value::{Value, NestedValue, Domain, IOValue, UnwrappedIOValue, Float, Double, Map};
|
|
use super::writer::Writer;
|
|
|
|
pub use super::writer::Result;
|
|
|
|
pub type EncodePlaceholderMap = Map<UnwrappedIOValue, usize>;
|
|
|
|
pub struct Encoder<'a, 'b, W: Writer> {
|
|
pub write: &'a mut W,
|
|
pub placeholders: Option<&'b EncodePlaceholderMap>,
|
|
}
|
|
|
|
impl<'a, 'b, W: Writer> Encoder<'a, 'b, W> {
|
|
pub fn new(write: &'a mut W, placeholders: Option<&'b EncodePlaceholderMap>) -> Self {
|
|
Encoder{ write, placeholders }
|
|
}
|
|
|
|
pub fn write(&mut self, v: &IOValue) -> Result {
|
|
for ann in v.annotations() {
|
|
self.write.write_annotation_prefix()?;
|
|
self.write(ann)?;
|
|
}
|
|
self.write_value(v.value())
|
|
}
|
|
|
|
pub fn write_value(&mut self, v: &UnwrappedIOValue) -> Result {
|
|
match self.placeholders.and_then(|m| m.get(v)) {
|
|
Some(&n) => self.write.write_placeholder_ref(n),
|
|
None => 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(ref b) => self.write.write_int(b),
|
|
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((ref l, ref fs)) => {
|
|
self.write.open_record(fs.len())?;
|
|
self.write(IOValue::boxunwrap(l))?;
|
|
for f in fs { 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()?)
|
|
}
|
|
}
|
|
}
|
|
}
|