oxihuman_export/
cbor_export.rs1#![allow(dead_code)]
4
5#[allow(dead_code)]
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum CborMajor {
11 Uint = 0,
12 NInt = 1,
13 Bytes = 2,
14 Text = 3,
15 Array = 4,
16 Map = 5,
17 Tag = 6,
18 Simple = 7,
19}
20
21#[allow(dead_code)]
23pub fn cbor_header(major: CborMajor, additional: u8) -> u8 {
24 ((major as u8) << 5) | (additional & 0x1F)
25}
26
27#[allow(dead_code)]
29pub fn encode_uint(val: u64) -> Vec<u8> {
30 cbor_encode_head(CborMajor::Uint, val)
31}
32
33#[allow(dead_code)]
35pub fn encode_text(s: &str) -> Vec<u8> {
36 let mut out = cbor_encode_head(CborMajor::Text, s.len() as u64);
37 out.extend_from_slice(s.as_bytes());
38 out
39}
40
41#[allow(dead_code)]
43pub fn encode_bytes(data: &[u8]) -> Vec<u8> {
44 let mut out = cbor_encode_head(CborMajor::Bytes, data.len() as u64);
45 out.extend_from_slice(data);
46 out
47}
48
49#[allow(dead_code)]
51pub fn encode_array_header(n: usize) -> Vec<u8> {
52 cbor_encode_head(CborMajor::Array, n as u64)
53}
54
55#[allow(dead_code)]
57pub fn encode_map_header(n: usize) -> Vec<u8> {
58 cbor_encode_head(CborMajor::Map, n as u64)
59}
60
61#[allow(dead_code)]
63pub fn encode_bool(val: bool) -> Vec<u8> {
64 vec![cbor_header(CborMajor::Simple, if val { 21 } else { 20 })]
65}
66
67#[allow(dead_code)]
69pub fn encode_null() -> Vec<u8> {
70 vec![cbor_header(CborMajor::Simple, 22)]
71}
72
73#[allow(dead_code)]
75pub fn encode_f32(val: f32) -> Vec<u8> {
76 let mut out = vec![cbor_header(CborMajor::Simple, 26)];
77 out.extend_from_slice(&val.to_bits().to_be_bytes());
78 out
79}
80
81#[allow(dead_code)]
83pub fn uint_byte_len(val: u64) -> usize {
84 encode_uint(val).len()
85}
86
87fn cbor_encode_head(major: CborMajor, val: u64) -> Vec<u8> {
88 if val <= 23 {
89 vec![cbor_header(major, val as u8)]
90 } else if val <= 0xFF {
91 vec![cbor_header(major, 24), val as u8]
92 } else if val <= 0xFFFF {
93 let bytes = (val as u16).to_be_bytes();
94 vec![cbor_header(major, 25), bytes[0], bytes[1]]
95 } else if val <= 0xFFFF_FFFF {
96 let bytes = (val as u32).to_be_bytes();
97 let mut out = vec![cbor_header(major, 26)];
98 out.extend_from_slice(&bytes);
99 out
100 } else {
101 let bytes = val.to_be_bytes();
102 let mut out = vec![cbor_header(major, 27)];
103 out.extend_from_slice(&bytes);
104 out
105 }
106}
107
108#[cfg(test)]
109mod tests {
110 use super::*;
111
112 #[test]
113 fn encode_uint_small() {
114 let b = encode_uint(0);
115 assert_eq!(b.len(), 1);
116 assert_eq!(b[0], 0x00);
117 }
118
119 #[test]
120 fn encode_uint_23() {
121 let b = encode_uint(23);
122 assert_eq!(b.len(), 1);
123 assert_eq!(b[0], 23);
124 }
125
126 #[test]
127 fn encode_uint_24() {
128 let b = encode_uint(24);
129 assert_eq!(b.len(), 2);
130 assert_eq!(b[0], cbor_header(CborMajor::Uint, 24));
131 }
132
133 #[test]
134 fn encode_text_hello() {
135 let b = encode_text("hi");
136 assert_eq!(b.len(), 3);
137 assert_eq!(b[1..], b"hi"[..]);
138 }
139
140 #[test]
141 fn encode_bytes_nonempty() {
142 let b = encode_bytes(&[0xDE, 0xAD]);
143 assert_eq!(b.len(), 3);
144 }
145
146 #[test]
147 fn encode_bool_true() {
148 let b = encode_bool(true);
149 assert_eq!(b[0], cbor_header(CborMajor::Simple, 21));
150 }
151
152 #[test]
153 fn encode_bool_false() {
154 let b = encode_bool(false);
155 assert_eq!(b[0], cbor_header(CborMajor::Simple, 20));
156 }
157
158 #[test]
159 fn encode_null_one_byte() {
160 let b = encode_null();
161 assert_eq!(b.len(), 1);
162 }
163
164 #[test]
165 fn encode_f32_five_bytes() {
166 let b = encode_f32(1.0);
167 assert_eq!(b.len(), 5);
168 }
169
170 #[test]
171 fn array_header_correct() {
172 let b = encode_array_header(3);
173 assert_eq!(b[0], cbor_header(CborMajor::Array, 3));
174 }
175}