Cbor Serialization - unable to compile


#1

I followed the 1st two examples in the link:
http://burntsushi.net/rustdoc/cbor/

On implementing serialization for custom DataType I am able to serialize the struct but unable to get the deserialize to compile.

struct CustomData {
  name: NameType,
  value: Vec<u8>,
}

impl Encodable for CustomData {
  fn encode<E: Encoder>(&self, e: &mut E)->Result<(), E::Error> {
    CborTagEncode {
      tag: 5483_001,
      data: &(&self.name, &self.value),
    }.encode(e)
  }
}

impl Decodable for CustomData {
  fn decode<D: Decoder>(d: &mut D)->Result<CustomData, D::Error> {
    try!(d.read_u64());
    Ok(CustomData {
      name: try!(Decodable::decode(d)),
      value: try!(Decodable::decode(d)),
    })
  }
}

then later:

 let mut e = cbor::Encoder::from_memory();
 obj_before.encode(&mut e);

 let mut d = cbor::Decoder::from_bytes(e.as_bytes());
 CustomData::decode(&mut d);

the encoding compiles fine but with decoder I get:

error: the trait `rustc-serialize::serialize::Decoder` is not implemented for the type `cbor::decoder::Decoder<std::io::cursor::Cursor<collections::vec::Vec<u8>>>` 

I’m from C++ background and am very new to rust :smile: (just the third day on it) so although i kind of get what the error message is saying I do not have the expertise to go into definitions/source-code to solve it. Can somebody help me here ?


#2

Hiya! There are a couple things wrong with your code. :smile:

First, the issue with your error is that Decoder doesn’t actually implement rustc_serialize::Decoder. Maybe that was a bad API decision on my part, but the intention was to expose a more convenient interface. e.g., See the cbor::Decoder::decode method, which yields an iterator of decoded results.

The second problem is that you encoded your data as a tuple, but you’re decoding it as two distinct data items. You should decode it the same way you encode it (as a tuple).

Here’s a full working program based off your code: https://gist.github.com/anonymous/8dc71078d25531e8af7e (In the future, it helps to submit a complete program. It makes debugging problems much easier!)


#3

Very nice, I wonder is it possible to just pull and/or query a single NV pair from an encoded stream ? i.e. in the above example say we wanted to query a cbor object with json type syntax

let name = decode("name", d)
and/or
if has("name", d)

Just as an example ? Sorry for simple questions, we are rushing through a quick test of some of this at the moment, so every bit of info helps.


#4

Any question is good!

Could you elaborate a little bit though? I’m not sure I understand your question. Maybe a more flushed out example. Pseudo code would help.

I’ll just say a little more though. The decode method gives you an iterator over all top-level data items. So if your name-value pairs are all top-level data items, it should just work.


#5

Thanks for the time, we did get it working right enough

  let obj_before = ImmutableData {
    name: NameType{ id: vec![3u8; 10] },
    value: vec![99u8; 10],
  };

  let mut e = cbor::Encoder::from_memory();
  e.encode(&[&obj_before]).unwrap();

  let mut d = cbor::Decoder::from_bytes(e.as_bytes());
  let obj_after: ImmutableData = d.decode().next().unwrap().unwrap();

  assert_eq!(obj_before.name.id, obj_after.name.id);
  assert_eq!(obj_before.value, obj_after.value);
} 

Where we had a couple of simple data structures with the Encoder and Decoder traits defined correctly. An issue we had was using an unnamed struct or whatever it’s called (typedef type thing) which was basically struct NameType( Vec<u8>) and this really needed named data elements to allow an Encode / decode trait to be written…

All looks OK now so thanks again, really nice work.


#6

@dirvine I was going to respond earlier and say that struct NameType(Vec<u8>) should work, and that if it doesn’t, then there’s a bug somewhere. Indeed, it turns out that you’ve uncovered a bug! It’s related to some significant contortions required in the Decoder implementation to support custom CBOR tags. I have a couple of ideas on how to fix it, but it will require a breaking change. Stay tuned—I’ll be sure to update the examples in the docs.


#7

@dirvine OK, this should be fixed now. Here’s an updated example: https://gist.github.com/dde703d5b9c5a856a39c

If you’re curious, here’s the fix, at which you may scream in horror. :slight_smile: https://github.com/BurntSushi/rust-cbor/commit/c6cddbc9831af800001ff2c15c3193e3220ce606#diff-26006a0497afb96d876927e114a7b29eR58


#8

Wow, brilliant work and quite a change. I think it is very much worthwhile though. Thanks so much for this, the rust community seems pretty terrific actually. Great to be part of it.