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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import_stdlib!();

use bytes::Bytes;

use crate::{CBOR, varint::{MajorType, EncodeVarInt}, CBORCase};

/// A type that can be encoded as CBOR.
pub trait CBOREncodable: Into<CBOR> {
    /// 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.case() {
            CBORCase::Unsigned(x) => x.cbor_data(),
            CBORCase::Negative(x) => {
                assert!(x < &0);
                x.cbor_data()
            },
            CBORCase::ByteString(x) => {
                let mut buf = x.len().encode_varint(MajorType::Bytes);
                buf.extend(x);
                buf
            },
            CBORCase::Text(x) => x.cbor_data(),
            CBORCase::Array(x) => x.cbor_data(),
            CBORCase::Map(x) => x.cbor_data(),
            CBORCase::Tagged(tag, item) => {
                let mut buf = tag.value().encode_varint(MajorType::Tagged);
                buf.extend(item.cbor_data());
                buf
            },
            CBORCase::Simple(x) => x.cbor_data(),
        }
    }
}

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

impl<T> From<&T> for CBOR where T: CBOREncodable {
    fn from(value: &T) -> Self {
        value.cbor()
    }
}

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

impl From<Box<CBOR>> for CBOR {
    fn from(value: Box<CBOR>) -> Self {
        value.cbor()
    }
}

impl CBOREncodable for Bytes {
    fn cbor(&self) -> CBOR {
        CBORCase::ByteString(self.clone()).into()
    }
}