dbus-serialize 0.1.1

Encoder / Decoder for D-Bus Types
Documentation
//! Implements the rustc_serialize::Encoder trait
use std::collections::HashMap;

use rustc_serialize::{Encoder,Encodable};

use types::{Value,BasicValue,Struct,Signature,Dictionary,Array};

pub struct DBusEncoder {
    val: Vec<Value>,
    signature: String,
    key: Option<BasicValue>
}

#[derive(Debug,PartialEq)]
pub enum EncoderError {
    BadKeyType,
    Unsupported,
    EmptyArray
}

impl DBusEncoder {
    fn handle_struct (&mut self) -> Result<(),EncoderError> {
        let mut objs = Vec::new();
        {
            let val = &self.val;
            for i in val {
                objs.push(i.clone());
            }
        }
        let s = Struct {
            objects: objs,
            signature: Signature("(".to_string() + &self.signature + ")")
        };
        self.signature = "".to_string();
        self.val.push(Value::Struct(s));
        Ok(())
    }

    fn handle_array (&mut self) -> Result<(),EncoderError> {
        let mut objs = Vec::new();
        for i in 0..self.val.len() {
            self.val.push(Value::BasicValue(BasicValue::Byte(0)));
            objs.push(self.val.swap_remove(i));
        }
        self.val.clear();
        self.val.push(Value::Array(Array::new(objs)));
        Ok(())
    }

    pub fn new() -> DBusEncoder {
        DBusEncoder {
            val: Vec::new(),
            signature: "".to_string(),
            key: None
        }
    }
    
    pub fn encode<T: Encodable>(obj: &T) -> Result<Value,EncoderError> {
        let mut encoder = DBusEncoder::new();
        try!(obj.encode(&mut encoder));
        Ok(encoder.val.remove(0))
    }
}

impl<T: Encodable> From<T> for Value {
    fn from(x: T) -> Value {
        DBusEncoder::encode(&x).unwrap()
    }
}

impl Encoder for DBusEncoder {
    type Error = EncoderError;

    fn emit_nil(&mut self) -> Result<(), Self::Error> {
        Err(EncoderError::Unsupported)
    }
    fn emit_usize(&mut self, v: usize) -> Result<(), Self::Error> {
        self.val.push(Value::BasicValue(BasicValue::Uint64(v as u64)));
        self.signature.push_str("n");
        Ok(())
    }
    fn emit_u64(&mut self, v: u64) -> Result<(), Self::Error> {
        self.val.push(Value::BasicValue(BasicValue::Uint64(v)));
        self.signature.push_str("n");
        Ok(())
    }
    fn emit_u32(&mut self, v: u32) -> Result<(), Self::Error> {
        self.val.push(Value::BasicValue(BasicValue::Uint32(v)));
        self.signature.push_str("u");
        Ok(())
    }
    fn emit_u16(&mut self, v: u16) -> Result<(), Self::Error> {
        self.val.push(Value::BasicValue(BasicValue::Uint16(v)));
        self.signature.push_str("q");
        Ok(())
    }
    fn emit_u8(&mut self, v: u8) -> Result<(), Self::Error> {
        self.val.push(Value::BasicValue(BasicValue::Byte(v)));
        self.signature.push_str("y");
        Ok(())
    }
    fn emit_isize(&mut self, v: isize) -> Result<(), Self::Error> {
        self.val.push(Value::BasicValue(BasicValue::Int64(v as i64)));
        self.signature.push_str("x");
        Ok(())
    }
    fn emit_i64(&mut self, v: i64) -> Result<(), Self::Error> {
        self.val.push(Value::BasicValue(BasicValue::Int64(v)));
        self.signature.push_str("x");
        Ok(())
    }
    fn emit_i32(&mut self, v: i32) -> Result<(), Self::Error> {
        self.val.push(Value::BasicValue(BasicValue::Int32(v)));
        self.signature.push_str("i");
        Ok(())
    }
    fn emit_i16(&mut self, v: i16) -> Result<(), Self::Error> {
        self.val.push(Value::BasicValue(BasicValue::Int16(v)));
        self.signature.push_str("n");
        Ok(())
    }
    fn emit_i8(&mut self, _v: i8) -> Result<(), Self::Error> {
        Err(EncoderError::Unsupported)
    }
    fn emit_bool(&mut self, v: bool) -> Result<(), Self::Error> {
        self.val.push(Value::BasicValue(BasicValue::Boolean(v)));
        self.signature.push_str("b");
        Ok(())
    }
    fn emit_f64(&mut self, v: f64) -> Result<(), Self::Error> {
        self.val.push(Value::Double(v));
        self.signature.push_str("d");
        Ok(())
    }
    fn emit_f32(&mut self, v: f32) -> Result<(), Self::Error> {
        self.val.push(Value::Double(v as f64));
        self.signature.push_str("d");
        Ok(())
    }
    fn emit_char(&mut self, v: char) -> Result<(), Self::Error> {
        self.val.push(Value::BasicValue(BasicValue::Byte(v as u8)));
        self.signature.push_str("y");
        Ok(())
    }
    fn emit_str(&mut self, v: &str) -> Result<(), Self::Error> {
        self.val.push(Value::BasicValue(BasicValue::String(v.to_string())));
        self.signature.push_str("s");
        Ok(())
    }

    fn emit_struct<F>(&mut self, _name: &str, _len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        try!(f(self));
        self.handle_struct()
    }
    fn emit_struct_field<F>(&mut self, _f_name: &str, _f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        f(self)
    }
    fn emit_tuple<F>(&mut self, _len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        try!(f(self));
        self.handle_struct()
    }
    fn emit_tuple_arg<F>(&mut self, _idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        f(self)
    }
    fn emit_tuple_struct<F>(&mut self, _name: &str, _len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        try!(f(self));
        self.handle_struct()
    }
    fn emit_tuple_struct_arg<F>(&mut self, _f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        f(self)
    }

    fn emit_seq<F>(&mut self, _len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        try!(f(self));
        self.handle_array()
    }
    fn emit_seq_elt<F>(&mut self, _idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        f(self)
    }

    fn emit_map<F>(&mut self, _len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        // Yes, i'm intentionally creating a Dictionary with an invalid signature...
        let map : Dictionary = Dictionary::new_with_sig(HashMap::new(), "".to_string());
        self.val.push(Value::Dictionary(map));
        try!(f(self));

        // Fix up the signature now that the map hopefully has elements in it.
        let x = match self.val.pop().unwrap() {
            Value::Dictionary(x) => x.map,
            _ => panic!("Where'd my dictionary go?!")
        };
        self.val.push(Value::Dictionary(Dictionary::new(x)));
        Ok(())
    }
    fn emit_map_elt_key<F>(&mut self, _idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        try!(f(self));
        self.key = match self.val.pop().unwrap() {
            Value::BasicValue(x) => Some(x),
            _ => return Err(EncoderError::BadKeyType)
        };
        Ok(())
    }
    fn emit_map_elt_val<F>(&mut self, _idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        let key : BasicValue = self.key.take().unwrap();
        try!(f(self));
        let val : Value = self.val.pop().unwrap();
        let mut map = self.val.pop().unwrap();
        match map {
            Value::Dictionary(ref mut x) => x.map.insert(key, val),
            _ => panic!("No dictionary on stack")
        };
        self.val.push(map);
        Ok(())
    }

    fn emit_option<F>(&mut self, _f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(EncoderError::Unsupported)
    }
    fn emit_option_none(&mut self) -> Result<(), Self::Error> {
        Err(EncoderError::Unsupported)
    }
    fn emit_option_some<F>(&mut self, _f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(EncoderError::Unsupported)
    }
    fn emit_enum<F>(&mut self, _name: &str, _f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(EncoderError::Unsupported)
    }
    fn emit_enum_variant<F>(&mut self, _v_name: &str, _v_id: usize, _len: usize, _f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(EncoderError::Unsupported)
    }
    fn emit_enum_variant_arg<F>(&mut self, _a_idx: usize, _f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(EncoderError::Unsupported)
    }
    fn emit_enum_struct_variant<F>(&mut self, _v_name: &str, _v_id: usize, _len: usize, _f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(EncoderError::Unsupported)
    }
    fn emit_enum_struct_variant_field<F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(EncoderError::Unsupported)
    }
}

#[test]
fn test_array() {
    let array : Vec<u32> = vec![1,2,3];
    let v = DBusEncoder::encode(&array).ok().unwrap();
    let a2 = vec![
        Value::BasicValue(BasicValue::Uint32(1)),
        Value::BasicValue(BasicValue::Uint32(2)),
        Value::BasicValue(BasicValue::Uint32(3)),
    ];
    assert_eq!(v, Value::Array(Array::new(a2)));
}