1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
use crate::{CBOR, varint::{MajorType, EncodeVarInt}};

/// A type that can be encoded as CBOR.
pub trait CBOREncodable {
    /// Returns the value in CBOR symbolic representation.
    fn cbor(&self) -> CBOR;
    /// Returns the value in CBOR binary representation.
    fn cbor_data(&self) -> Vec<u8> {
        self.cbor().cbor_data()
    }
}

impl CBOREncodable for CBOR {
    fn cbor(&self) -> CBOR {
        self.clone()
    }

    fn cbor_data(&self) -> Vec<u8> {
        match self {
            CBOR::Unsigned(x) => x.cbor_data(),
            CBOR::Negative(x) => {
                assert!(x < &0);
                x.cbor_data()
            },
            CBOR::ByteString(x) => {
                let mut buf = x.len().encode_varint(MajorType::Bytes);
                buf.extend(x);
                buf
            },
            CBOR::Text(x) => x.cbor_data(),
            CBOR::Array(x) => x.cbor_data(),
            CBOR::Map(x) => x.cbor_data(),
            CBOR::Tagged(tag, item) => {
                let mut buf = tag.value().encode_varint(MajorType::Tagged);
                buf.extend(item.cbor_data());
                buf
            },
            CBOR::Simple(x) => x.cbor_data(),
        }
    }
}

impl<T> CBOREncodable for &T where T: CBOREncodable {
    fn cbor(&self) -> CBOR {
        (*self).cbor()
    }
}