use num::bigint::BigInt; use std::io::Error; use super::signed_integer::SignedIntegerRepr; use super::repr::{Value, NestedValue, IOValue, UnwrappedIOValue, Float, Double}; pub type Result = std::result::Result; pub trait AnnotationWriter: Writer { fn start_annotation(&mut self) -> Result<()>; fn start_value(&mut self) -> Result<()>; } pub trait CompoundWriter: Writer { fn extend(&mut self) -> Result<()>; fn delimit(&mut self) -> Result<()>; } pub trait Writer: Sized { type AnnWriter: AnnotationWriter; type SeqWriter: CompoundWriter; type SetWriter: CompoundWriter; type EmbeddedWriter: Writer; fn align(&mut self, natural_chunksize: u64) -> Result<()>; fn start_annotations(&mut self) -> Result; fn end_annotations(&mut self, ann: Self::AnnWriter) -> Result<()>; fn write_bool(&mut self, v: bool) -> Result<()>; fn write_f32(&mut self, v: f32) -> Result<()>; fn write_f64(&mut self, v: f64) -> Result<()>; fn write_i8(&mut self, v: i8) -> Result<()>; fn write_u8(&mut self, v: u8) -> Result<()>; fn write_i16(&mut self, v: i16) -> Result<()>; fn write_u16(&mut self, v: u16) -> Result<()>; fn write_i32(&mut self, v: i32) -> Result<()>; fn write_u32(&mut self, v: u32) -> Result<()>; fn write_i64(&mut self, v: i64) -> Result<()>; fn write_u64(&mut self, v: u64) -> Result<()>; fn write_i128(&mut self, v: i128) -> Result<()>; fn write_u128(&mut self, v: u128) -> Result<()>; fn write_int(&mut self, v: &BigInt) -> Result<()>; fn write_string(&mut self, v: &str) -> Result<()>; fn write_bytes(&mut self, v: &[u8]) -> Result<()>; fn write_symbol(&mut self, v: &str) -> Result<()>; fn start_record(&mut self, field_count: Option) -> Result; fn start_sequence(&mut self, item_count: Option) -> Result; fn end_seq(&mut self, seq: Self::SeqWriter) -> Result<()>; fn start_set(&mut self, item_count: Option) -> Result; fn start_dictionary(&mut self, entry_count: Option) -> Result; fn end_set(&mut self, set: Self::SetWriter) -> Result<()>; fn start_embedded(&mut self) -> Result; fn end_embedded(&mut self, ptr: Self::EmbeddedWriter) -> Result<()>; //--------------------------------------------------------------------------- fn write(&mut self, v: &IOValue) -> Result<()> { match v.annotations().maybe_slice() { None => { self.write_value(v.value())?; } Some(anns) => { let mut a = self.start_annotations()?; for ann in anns { a.start_annotation()?; a.write(ann)?; } a.start_value()?; a.write_value(v.value())?; self.end_annotations(a)?; } } Ok(()) } fn write_value(&mut self, v: &UnwrappedIOValue) -> Result<()> { match v { Value::Boolean(b) => self.write_bool(*b), Value::Float(Float(f)) => self.write_f32(*f), Value::Double(Double(d)) => self.write_f64(*d), Value::SignedInteger(n) => match n.repr() { SignedIntegerRepr::I128(i) => self.write_i128(*i), SignedIntegerRepr::U128(u) => self.write_u128(*u), SignedIntegerRepr::Big(n) => self.write_int(n), } Value::String(s) => self.write_string(s), Value::ByteString(bs) => self.write_bytes(bs), Value::Symbol(s) => self.write_symbol(s), Value::Record(r) => { let mut c = self.start_record(Some(r.arity()))?; c.extend()?; c.write(r.label())?; c.delimit()?; for f in r.fields() { c.extend()?; c.write(f)?; c.delimit()?; } self.end_seq(c) } Value::Sequence(vs) => { let mut c = self.start_sequence(Some(vs.len()))?; for v in vs { c.extend()?; c.write(v)?; c.delimit()?; } self.end_seq(c) } Value::Set(vs) => { let mut c = self.start_set(Some(vs.len()))?; for v in vs { c.extend()?; c.write(v)?; c.delimit()?; } self.end_set(c) } Value::Dictionary(vs) => { let mut c = self.start_dictionary(Some(vs.len()))?; for (k, v) in vs { c.extend()?; c.write(k)?; c.write(v)?; c.delimit()?; } self.end_set(c) } Value::Embedded(d) => { let mut c = self.start_embedded()?; c.write(&d)?; self.end_embedded(c) } } } } pub fn varint(w: &mut W, mut v: u64) -> Result { let mut byte_count = 0; loop { byte_count += 1; if v < 128 { w.write_all(&[v as u8])?; return Ok(byte_count); } else { w.write_all(&[((v & 0x7f) + 128) as u8])?; v >>= 7; } } }