makepad_live_compiler/
live_node_cbor.rs

1use {
2    std::rc::Rc,
3    std::convert::TryInto,
4    crate::{
5        makepad_live_tokenizer::LiveId,
6        live_node::*,
7    }
8};
9
10pub trait LiveNodeSliceToCbor {
11    fn to_cbor(&self, parent_index: usize) -> Result<Vec<u8>, String>;
12}
13
14pub trait LiveNodeVecFromCbor {
15    fn from_cbor(&mut self, buf: &[u8]) -> Result<(), LiveNodeFromCborError>;
16}
17
18//0x00..0x17	unsigned integer 0x00..0x17 (0..23)
19const CBOR_UINT_START: u8 = 0x00;
20const CBOR_UINT_END: u8 = 0x17;
21const CBOR_U8: u8 = 0x18; //	unsigned integer (one-byte uint8_t follows)
22const CBOR_U16: u8 = 0x19; // unsigned integer (two - byte uint16_t follows)
23const CBOR_U32: u8 = 0x1a; //	unsigned integer (four-byte uint32_t follows)
24const CBOR_U64: u8 = 0x1b; //	unsigned integer (eight-byte uint64_t follows)
25const CBOR_NUINT_START: u8 = 0x20; //..0x37	negative integer -1-0x00..-1-0x17 (-1..-24)
26const CBOR_NUINT_END: u8 = 0x37; //..0x37	negative integer -1-0x00..-1-0x17 (-1..-24)
27const CBOR_NU8: u8 = 0x38; //	negative integer -1-n (one-byte uint8_t for n follows)
28const CBOR_NU16: u8 = 0x39; //	negative integer -1-n (two-byte uint16_t for n follows)
29const CBOR_NU32: u8 = 0x3a; //	negative integer -1-n (four-byte uint32_t for n follows)
30const CBOR_NU64: u8 = 0x3b; //	negative integer -1-n (eight-byte uint64_t for n follows)
31const CBOR_BSTR_START: u8 = 0x40; //..0x57	byte string (0x00..0x17 bytes follow)
32const CBOR_BSTR_END: u8 = 0x57; //..0x57	byte string (0x00..0x17 bytes follow)
33const CBOR_BSTR_8: u8 = 0x58; //	byte string (one-byte uint8_t for n, and then n bytes follow)
34const CBOR_BSTR_16: u8 = 0x59; //	byte string (two-byte uint16_t for n, and then n bytes follow)
35const CBOR_BSTR_32: u8 = 0x5a; //	byte string (four-byte uint32_t for n, and then n bytes follow)
36const CBOR_BSTR_64: u8 = 0x5b; //	byte string (eight-byte uint64_t for n, and then n bytes follow)
37const CBOR_BSTR_BRK: u8 = 0x5f; //	byte string, byte strings follow, terminated by "break"
38const CBOR_UTF8_START: u8 = 0x60; //..0x77	UTF-8 string (0x00..0x17 bytes follow)
39const CBOR_UTF8_END: u8 = 0x77; //..0x77	UTF-8 string (0x00..0x17 bytes follow)
40const CBOR_UTF8_8: u8 = 0x78; //	UTF-8 string (one-byte uint8_t for n, and then n bytes follow)
41const CBOR_UTF8_16: u8 = 0x79; //	UTF-8 string (two-byte uint16_t for n, and then n bytes follow)
42const CBOR_UTF8_32: u8 = 0x7a; //	UTF-8 string (four-byte uint32_t for n, and then n bytes follow)
43const CBOR_UTF8_64: u8 = 0x7b; //	UTF-8 string (eight-byte uint64_t for n, and then n bytes follow)
44const CBOR_UTF8_BRK: u8 = 0x7f; //	UTF-8 string, UTF-8 strings follow, terminated by "break"
45const CBOR_ARRAY_START: u8 = 0x80; //..0x97	array (0x00..0x17 data items follow)
46const CBOR_ARRAY_END: u8 = 0x97; //..0x97	array (0x00..0x17 data items follow)
47const CBOR_ARRAY_8: u8 = 0x98; //	array (one-byte uint8_t for n, and then n data items follow)
48const CBOR_ARRAY_16: u8 = 0x99; //	array (two-byte uint16_t for n, and then n data items follow)
49const CBOR_ARRAY_32: u8 = 0x9a; //	array (four-byte uint32_t for n, and then n data items follow)
50const CBOR_ARRAY_64: u8 = 0x9b; //	array (eight-byte uint64_t for n, and then n data items follow)
51const CBOR_ARRAY_BRK: u8 = 0x9f; //	array, data items follow, terminated by "break"
52const CBOR_MAP_START: u8 = 0xa0; //..0xb7	map (0x00..0x17 pairs of data items follow)
53const CBOR_MAP_END: u8 = 0xb7; //..0xb7	map (0x00..0x17 pairs of data items follow)
54const CBOR_MAP_8: u8 = 0xb8; //	map (one-byte uint8_t for n, and then n pairs of data items follow)
55const CBOR_MAP_16: u8 = 0xb9; //	map (two-byte uint16_t for n, and then n pairs of data items follow)
56const CBOR_MAP_32: u8 = 0xba; //	map (four-byte uint32_t for n, and then n pairs of data items follow)
57const CBOR_MAP_64: u8 = 0xbb; //	map (eight-byte uint64_t for n, and then n pairs of data items follow)
58const CBOR_MAP_BRK: u8 = 0xbf; //	map, pairs of data items follow, terminated by "break"
59const CBOR_TIME_TEXT: u8 = 0xc0; //	text-based date/time (data item follows; see Section 3.4.1)
60const CBOR_TIME_EPOCH: u8 = 0xc1; //	epoch-based date/time (data item follows; see Section 3.4.2)
61const CBOR_UBIGNUM: u8 = 0xc2; //	unsigned bignum (data item "byte string" follows)
62const CBOR_NBIGNUM: u8 = 0xc3; //	negative bignum (data item "byte string" follows)
63const CBOR_DECFRACT: u8 = 0xc4; //	decimal Fraction (data item "array" follows; see Section 3.4.4)
64const CBOR_BIGFLOAT: u8 = 0xc5; //	bigfloat (data item "array" follows; see Section 3.4.4)
65const CBOR_TAG_START: u8 = 0xc6; //..0xd4	(tag)
66const CBOR_TAG_END: u8 = 0xd4; //..0xd4	(tag)
67const CBOR_CONV_START: u8 = 0xd5; //..0xd7	expected conversion (data item follows; see Section 3.4.5.2)
68const CBOR_CONV_END: u8 = 0xd7; //..0xd7	expected conversion (data item follows; see Section 3.4.5.2)
69const CBOR_MTAG_START: u8 = 0xd8; //..0xdb	(more tags; 1/2/4/8 bytes of tag number and then a data item follow)
70const CBOR_MTAG_END: u8 = 0xdb; //..0xdb	(more tags; 1/2/4/8 bytes of tag number and then a data item follow)
71const CBOR_SIMPLE_START: u8 = 0xe0; //..0xf3	(simple value)
72const CBOR_SIMPLE_END: u8 = 0xf3; //..0xf3	(simple value)
73const CBOR_FALSE: u8 = 0xf4; //	false
74const CBOR_TRUE: u8 = 0xf5; //	true
75const CBOR_NULL: u8 = 0xf6; //	null
76const CBOR_UNDEIFNED: u8 = 0xf7; //	undefined
77const CBOR_SIMPLE_8: u8 = 0xf8; //	(simple value, one byte follows)
78const CBOR_FLOAT16: u8 = 0xf9; //	half-precision float (two-byte IEEE 754)
79const CBOR_FLOAT32: u8 = 0xfa; //	single-precision float (four-byte IEEE 754)
80const CBOR_FLOAT64: u8 = 0xfb; //	double-precision float (eight-byte IEEE 754)
81const CBOR_BREAK: u8 = 0xff; //	"break" stop code
82
83/* some Rust keyword abuse here 
84key:{move:{}} // clone
85key:{dyn:{}} // dyn created
86key:{ref:{}} // template
87key:{in:[v1,v2]} // vec
88key:{as:u32} // color
89key {enum:"String"} // enum
90*/
91
92impl<T> LiveNodeSliceToCbor for T where T: AsRef<[LiveNode]> {
93    fn to_cbor(&self, parent_index: usize) -> Result<Vec<u8>, String> {
94        let mut out = Vec::new();
95        let nodes = self.as_ref();
96        let mut index = parent_index;
97        
98        struct StackItem {index: usize, count: usize, has_keys: bool}
99        
100        let mut stack = vec![StackItem {index: 0, count: 0, has_keys: false}];
101        
102        while index < nodes.len() {
103            let node = &nodes[index];
104            
105            if node.value.is_close() {
106                if stack.is_empty() {
107                    return Err("Unmatched closed".into())
108                }
109                let item = stack.pop().unwrap();
110                if item.count > std::u16::MAX as usize {
111                    out[item.index] = if item.has_keys {CBOR_MAP_32}else {CBOR_ARRAY_32};
112                    let bytes = (item.count as u32).to_be_bytes();
113                    out.splice(item.index + 1..item.index + 1, bytes.iter().cloned());
114                }
115                else if item.count > std::u8::MAX as usize {
116                    out[item.index] = if item.has_keys {CBOR_MAP_16}else {CBOR_ARRAY_16};
117                    let bytes = (item.count as u16).to_be_bytes();
118                    out.splice(item.index + 1..item.index + 1, bytes.iter().cloned());
119                }
120                else if item.count >= 32 {
121                    out[item.index] = if item.has_keys {CBOR_MAP_8}else {CBOR_ARRAY_8};
122                    let bytes = (item.count as u8).to_be_bytes();
123                    out.splice(item.index + 1..item.index + 1, bytes.iter().cloned());
124                }
125                else {
126                    out[item.index] += item.count as u8
127                }
128                index += 1;
129                continue;
130            }
131            
132            let item = stack.last_mut().unwrap();
133            item.count += 1;
134            
135            if item.has_keys {
136                encode_id(node.id, &mut out);
137            }
138            
139            fn encode_u32(v: u32, out: &mut Vec<u8>) {
140                if v <= CBOR_UINT_END as u32 {
141                    out.push(v as u8)
142                }
143                else if v <= std::u8::MAX as u32 {
144                    out.push(CBOR_U8);
145                    out.push(v as u8)
146                }
147                else if v <= std::u16::MAX as u32 {
148                    out.push(CBOR_U16);
149                    out.extend_from_slice(&(v as u16).to_be_bytes());
150                }
151                else {
152                    out.push(CBOR_U32);
153                    out.extend_from_slice(&v.to_be_bytes());
154                }
155            }
156            
157            fn encode_u64(v: u64, out: &mut Vec<u8>) {
158                if v <= std::u32::MAX as u64 {
159                    encode_u32(v as u32, out);
160                }
161                else {
162                    out.push(CBOR_U64);
163                    out.extend_from_slice(&v.to_be_bytes());
164                }
165            }
166            
167            fn encode_i64(v: i64, out: &mut Vec<u8>) {
168                if v < 0 {
169                    let v = ((-v) - 1) as u64;
170                    if v <= (CBOR_NUINT_END - CBOR_NUINT_START) as u64 {
171                        out.push(CBOR_NUINT_START + v as u8);
172                    }
173                    else if v <= std::u8::MAX as u64 {
174                        out.push(CBOR_NU8);
175                        out.extend_from_slice(&(v as u8).to_be_bytes());
176                    }
177                    else if v <= std::u16::MAX as u64 {
178                        out.push(CBOR_NU16);
179                        out.extend_from_slice(&(v as u16).to_be_bytes());
180                    }
181                    else if v <= std::u32::MAX as u64 {
182                        out.push(CBOR_NU32);
183                        out.extend_from_slice(&(v as u32).to_be_bytes());
184                    }
185                    else {
186                        out.push(CBOR_NU64);
187                        out.extend_from_slice(&v.to_be_bytes());
188                    }
189                }
190                else {
191                    encode_u64(v as u64, out);
192                }
193            }
194            
195            fn encode_f32(v: f32, out: &mut Vec<u8>) {
196                if v.fract() == 0.0 {
197                    encode_i64(v as i64, out)
198                }
199                else {
200                    out.push(CBOR_FLOAT32);
201                    out.extend_from_slice(&v.to_be_bytes());
202                }
203            }
204            
205            fn encode_f64(v: f64, out: &mut Vec<u8>) {
206                if v.fract() == 0.0 {
207                    encode_i64(v as i64, out)
208                }
209                else {
210                    out.push(CBOR_FLOAT64);
211                    out.extend_from_slice(&v.to_be_bytes());
212                }
213            }
214            
215            fn encode_id(id: LiveId, out: &mut Vec<u8>) {
216                if id.0 & 0x8000_0000_0000_0000 == 0 {
217                    encode_u64(id.0, out);
218                }
219                else {
220                    id.as_string( | v | {
221                        if let Some(v) = v {
222                            encode_str(v, out);
223                        }
224                        else {
225                            encode_u64(id.0, out);
226                        }
227                    });
228                }
229            }
230            
231            let prop_type = node.origin.prop_type();
232            if prop_type != LivePropType::Field && prop_type != LivePropType::Nameless {
233                return Err("Non field types not implemented".into())
234            }
235            
236            fn encode_str(s: &str, out: &mut Vec<u8>) {
237                let len = s.len();
238                if len <= (CBOR_UTF8_END - CBOR_UTF8_START) as usize {
239                    out.push(len as u8 + CBOR_UTF8_START);
240                    out.extend_from_slice(s.as_bytes());
241                }
242                else if len <= std::u8::MAX as usize {
243                    out.push(CBOR_UTF8_8);
244                    out.push(len as u8);
245                    out.extend_from_slice(s.as_bytes());
246                }
247                else if len <= std::u16::MAX as usize {
248                    out.push(CBOR_UTF8_16);
249                    out.extend_from_slice(&(len as u16).to_be_bytes());
250                    out.extend_from_slice(s.as_bytes());
251                }
252                else if len <= std::u32::MAX as usize {
253                    out.push(CBOR_UTF8_32);
254                    out.extend_from_slice(&(len as u32).to_be_bytes());
255                    out.extend_from_slice(s.as_bytes());
256                }
257                else {
258                    out.push(CBOR_UTF8_64);
259                    out.extend_from_slice(&(len as u64).to_be_bytes());
260                    out.extend_from_slice(s.as_bytes());
261                }
262            }
263            //log!("SAVING {:?} {}", node.value, out.len());
264            match &node.value {
265                LiveValue::None => {
266                    out.push(CBOR_NULL);
267                },
268                LiveValue::Str(s) => {
269                    encode_str(s, &mut out);
270                },
271                LiveValue::InlineString(s) => {
272                    encode_str(s.as_str(), &mut out);
273                },
274                LiveValue::String(s) => {
275                    encode_str(s.as_str(), &mut out);
276                },
277                LiveValue::Bool(v) => {
278                    out.push(if *v {CBOR_TRUE} else {CBOR_FALSE});
279                }
280                LiveValue::Int64(v) => {
281                    encode_i64(*v, &mut out);
282                }
283                LiveValue::Float32(v) => {
284                    encode_f32(*v, &mut out);
285                },
286                LiveValue::Float64(v) => {
287                    encode_f64(*v, &mut out);
288                },
289                LiveValue::Color(v) => {
290                    out.push(1 + CBOR_MAP_START);
291                    encode_str("as", &mut out);
292                    encode_u32(*v, &mut out);
293                },
294                LiveValue::Vec2(v) => {
295                    out.push(1 + CBOR_MAP_START);
296                    encode_str("in", &mut out);
297                    out.push(2 + CBOR_ARRAY_START);
298                    encode_f32(v.x, &mut out);
299                    encode_f32(v.x, &mut out);
300                },
301                LiveValue::Vec3(v) => {
302                    out.push(1 + CBOR_MAP_START);
303                    encode_str("in", &mut out);
304                    out.push(3 + CBOR_ARRAY_START);
305                    encode_f32(v.x, &mut out);
306                    encode_f32(v.x, &mut out);
307                    encode_f32(v.z, &mut out);
308                },
309                LiveValue::Vec4(v) => {
310                    out.push(1 + CBOR_MAP_START);
311                    encode_str("in", &mut out);
312                    out.push(4 + CBOR_ARRAY_START);
313                    encode_f32(v.x, &mut out);
314                    encode_f32(v.x, &mut out);
315                    encode_f32(v.z, &mut out);
316                    encode_f32(v.w, &mut out);
317                },
318                LiveValue::BareEnum(variant) => {
319                    out.push(1 + CBOR_MAP_START);
320                    encode_str("if", &mut out);
321                    encode_id(*variant, &mut out);
322                },
323                LiveValue::Array => {
324                    stack.push(StackItem {index: out.len(), count: 0, has_keys: false});
325                    out.push(CBOR_ARRAY_START);
326                },
327                LiveValue::TupleEnum(variant) => {
328                    out.push(1 + CBOR_MAP_START);
329                    encode_str("enum", &mut out);
330                    out.push(2 + CBOR_ARRAY_START);
331                    encode_id(*variant, &mut out);
332                    stack.push(StackItem {index: out.len(), count: 0, has_keys: false});
333                    out.push(CBOR_ARRAY_START);
334                },
335                LiveValue::NamedEnum(variant) => {
336                    out.push(1 + CBOR_MAP_START);
337                    encode_str("enum", &mut out);
338                    out.push(2 + CBOR_ARRAY_START);
339                    encode_id(*variant, &mut out);
340                    stack.push(StackItem {index: out.len(), count: 0, has_keys: true});
341                    out.push(CBOR_MAP_START);
342                },
343                LiveValue::Object => {
344                    stack.push(StackItem {index: out.len(), count: 0, has_keys: true});
345                    out.push(CBOR_MAP_START);
346                }, // subnodes including this one
347                LiveValue::Close => {},
348                // TODO ITEMS
349                LiveValue::Id(_) => {
350                    return Err("Cannot serialise LiveValue::Id".into())
351                },
352                LiveValue::Clone(_) => {
353                    return Err("Cannot serialise LiveValue::Clone".into())
354                }, // subnodes including this one
355                LiveValue::ExprBinOp(_) => {
356                    return Err("Cannot serialise LiveValue::ExprBinOp".into())
357                },
358                LiveValue::ExprUnOp(_) => {
359                    return Err("Cannot serialise LiveValue::ExprUnOp".into())
360                },
361                LiveValue::ExprMember(_) => {
362                    return Err("Cannot serialise LiveValue::ExprMember".into())
363                },
364                LiveValue::Expr {..} => {
365                    return Err("Cannot serialise LiveValue::Expr".into())
366                },
367                LiveValue::ExprCall {..} => {
368                    return Err("Cannot serialise LiveValue::ExprCall".into())
369                },
370                LiveValue::Dependency {..} => {
371                    return Err("Cannot serialise LiveValue::Dependency".into())
372                },
373                LiveValue::Class {..} => {
374                    return Err("Cannot serialise LiveValue::Class".into())
375                }, // subnodes including this one
376                LiveValue::DSL {..} => {
377                    return Err("Cannot serialise LiveValue::DSL".into())
378                },
379                LiveValue::Import(..) => {
380                    return Err("Cannot serialise LiveValue::Import".into())
381                }
382                LiveValue::Root{..} => {
383                    return Err("Cannot serialise LiveValue::Registry".into())
384                }
385                LiveValue::IdPath(..) => {
386                    return Err("Cannot serialise LiveValue::IdPath".into())
387                }                
388            }
389            index += 1;
390        }
391        if stack.len() > 1 {
392            return Err("Uneven stack, not enough closes".into())
393        }
394        Ok(out)
395    }
396}
397
398// todo: pack these in somehow
399/*
400const BIN_EXPR_BIN_OP: u8 = 27;
401const BIN_EXPR_UN_OP: u8 = 28;
402const BIN_EXPR_MEMBER: u8 = 29;
403const BIN_EXPR: u8 = 30;
404const BIN_EXPR_CALL: u8 = 31;
405*/
406
407// compressed number values
408
409#[derive(Debug)]
410pub enum LiveNodeFromCborError {
411    OutOfBounds,
412    UnexpectedVariant,
413    LiveIdCollision,
414    ExpectedId,
415    NotImpl,
416    UnexpectedValue,
417    ExpectedBareEnumString,
418    StackNotClosed,
419    UTF8Error
420}
421
422impl LiveNodeVecFromCbor for Vec<LiveNode> {
423    
424    fn from_cbor(&mut self, data: &[u8]) -> Result<(), LiveNodeFromCborError> {
425        // alright lets decode msgpack livenodes
426        
427        fn assert_len(o: usize, len: usize, data: &[u8]) -> Result<(), LiveNodeFromCborError> {
428            if o + len > data.len() {panic!()} //return Err(LiveNodeFromBinaryError::OutOfBounds);}
429            Ok(())
430        }
431        
432        fn read_u8(data: &[u8], o: &mut usize) -> Result<u8, LiveNodeFromCborError> {
433            assert_len(*o, 1, data) ?;
434            let d = data[*o];
435            *o += 1;
436            Ok(d)
437        }
438        
439        fn read_u16(data: &[u8], o: &mut usize) -> Result<u16, LiveNodeFromCborError> {
440            assert_len(*o, 2, data) ?;
441            let d = u16::from_be_bytes(data[*o..*o + 2].try_into().unwrap());
442            *o += 2;
443            Ok(d)
444        }
445        
446        fn read_u32(data: &[u8], o: &mut usize) -> Result<u32, LiveNodeFromCborError> {
447            assert_len(*o, 4, data) ?;
448            let d = u32::from_be_bytes(data[*o..*o + 4].try_into().unwrap());
449            *o += 4;
450            Ok(d)
451        }
452        
453        fn read_u64(data: &[u8], o: &mut usize) -> Result<u64, LiveNodeFromCborError> {
454            assert_len(*o, 8, data) ?;
455            let d = u64::from_be_bytes(data[*o..*o + 8].try_into().unwrap());
456            *o += 8;
457            Ok(d)
458        }
459        
460        fn read_i8(data: &[u8], o: &mut usize) -> Result<i8, LiveNodeFromCborError> {
461            assert_len(*o, 1, data) ?;
462            let d = i8::from_be_bytes(data[*o..*o + 1].try_into().unwrap());
463            *o += 1;
464            Ok(d)
465        }
466        
467        fn read_i16(data: &[u8], o: &mut usize) -> Result<i16, LiveNodeFromCborError> {
468            assert_len(*o, 2, data) ?;
469            let d = i16::from_be_bytes(data[*o..*o + 2].try_into().unwrap());
470            *o += 2;
471            Ok(d)
472        }
473        
474        fn read_i32(data: &[u8], o: &mut usize) -> Result<i32, LiveNodeFromCborError> {
475            assert_len(*o, 4, data) ?;
476            let d = i32::from_be_bytes(data[*o..*o + 4].try_into().unwrap());
477            *o += 4;
478            Ok(d)
479        }
480        
481        fn read_i64(data: &[u8], o: &mut usize) -> Result<i64, LiveNodeFromCborError> {
482            assert_len(*o, 8, data) ?;
483            let d = i64::from_be_bytes(data[*o..*o + 8].try_into().unwrap());
484            *o += 8;
485            Ok(d)
486        }
487        
488        fn read_f32(data: &[u8], o: &mut usize) -> Result<f32, LiveNodeFromCborError> {
489            assert_len(*o, 4, data) ?;
490            let d = f32::from_be_bytes(data[*o..*o + 4].try_into().unwrap());
491            *o += 4;
492            Ok(d)
493        }
494        
495        fn read_f64(data: &[u8], o: &mut usize) -> Result<f64, LiveNodeFromCborError> {
496            assert_len(*o, 8, data) ?;
497            let d = f64::from_be_bytes(data[*o..*o + 8].try_into().unwrap());
498            *o += 8;
499            Ok(d)
500        }
501        
502        fn decode_str<'a>(data: &'a [u8], o: &mut usize) -> Result<Option<&'a str>,
503        LiveNodeFromCborError> {
504            assert_len(*o, 1, data) ?;
505            let len = if data[*o] >= CBOR_UTF8_START && data[*o] <= CBOR_UTF8_END {
506                let r = (data[*o] - CBOR_UTF8_START) as usize;
507                *o += 1;
508                r
509            }
510            else {
511                match data[*o] {
512                    CBOR_UTF8_8 => {
513                        *o += 1;
514                        read_u8(data, o) ? as usize
515                    }
516                    CBOR_UTF8_16 => {
517                        *o += 1;
518                        read_u16(data, o) ? as usize
519                    }
520                    CBOR_UTF8_32 => {
521                        *o += 1;
522                        read_u32(data, o) ? as usize
523                    }
524                    CBOR_UTF8_64 => {
525                        *o += 1;
526                        read_u64(data, o) ? as usize
527                    }
528                    _ => return Ok(None)
529                }
530            };
531            assert_len(*o, len, data) ?;
532            if let Ok(val) = std::str::from_utf8(&data[*o..*o + len]) {
533                *o += len;
534                Ok(Some(val))
535            } else {
536                Err(LiveNodeFromCborError::UTF8Error)
537            }
538        }
539        
540        fn decode_u64(data: &[u8], o: &mut usize) -> Result<Option<u64>, LiveNodeFromCborError> {
541            assert_len(*o, 1, data) ?;
542            let v = if data[*o] <= CBOR_UINT_END {
543                let r = Some(data[*o] as u64);
544                *o += 1;
545                r
546            }
547            else {
548                match data[*o] {
549                    CBOR_U8 => {
550                        *o += 1;
551                        Some(read_u8(data, o) ? as u64)
552                    }
553                    CBOR_U16 => {
554                        *o += 1;
555                        Some(read_u16(data, o) ? as u64)
556                    }
557                    CBOR_U32 => {
558                        *o += 1;
559                        Some(read_u32(data, o) ? as u64)
560                    }
561                    CBOR_U64 => {
562                        *o += 1;
563                        Some(read_u64(data, o)?)
564                    }
565                    _ => return Ok(None)
566                }
567            };
568            Ok(v)
569        }
570        
571        fn decode_i64(data: &[u8], o: &mut usize) -> Result<Option<i64>, LiveNodeFromCborError> {
572            assert_len(*o, 1, data) ?;
573            let v = if data[*o] >= CBOR_NUINT_START && data[*o] <= CBOR_NUINT_END {
574                let r = Some(-((data[*o] - CBOR_NUINT_START + 1) as i64));
575                *o += 1;
576                r
577            }
578            else {
579                match data[*o] {
580                    CBOR_NU8 => {
581                        *o += 1;
582                        Some(-(read_i8(data, o) ? as i64 + 1))
583                    }
584                    CBOR_NU16 => {
585                        *o += 1;
586                        Some(-(read_i16(data, o) ? as i64 + 1))
587                    }
588                    CBOR_NU32 => {
589                        *o += 1;
590                        Some(-(read_i32(data, o) ? as i64 + 1))
591                    }
592                    CBOR_NU64 => {
593                        *o += 1;
594                        Some(-(read_i64(data, o)? + 1))
595                    }
596                    _ => decode_u64(data, o)?.map(|data| data as i64)
597                }
598            };
599            Ok(v)
600        }
601        
602        fn decode_array_len(data: &[u8], o: &mut usize) -> Result<Option<usize>, LiveNodeFromCborError> {
603            assert_len(*o, 1, data) ?;
604            let v = if data[*o] >= CBOR_ARRAY_START && data[*o] <= CBOR_ARRAY_END {
605                let r = Some((data[*o] - CBOR_ARRAY_START) as usize);
606                *o += 1;
607                r
608            }
609            else {
610                match data[*o] {
611                    CBOR_ARRAY_8 => {
612                        *o += 1;
613                        Some(read_u8(data, o) ? as usize)
614                    }
615                    CBOR_ARRAY_16 => {
616                        *o += 1;
617                        Some(read_u16(data, o) ? as usize)
618                    }
619                    CBOR_ARRAY_32 => {
620                        *o += 1;
621                        Some(read_u32(data, o) ? as usize)
622                    }
623                    CBOR_ARRAY_64 => {
624                        *o += 1;
625                        Some(read_u64(data, o) ? as usize)
626                    }
627                    _ => return Ok(None)
628                }
629            };
630            Ok(v)
631        }
632        
633        fn decode_map_len(data: &[u8], o: &mut usize) -> Result<Option<usize>, LiveNodeFromCborError> {
634            assert_len(*o, 1, data) ?;
635            let v = if data[*o] >= CBOR_MAP_START && data[*o] <= CBOR_MAP_END {
636                let r = Some((data[*o] - CBOR_MAP_START) as usize);
637                *o += 1;
638                r
639            }
640            else {
641                match data[*o] {
642                    CBOR_MAP_8 => {
643                        *o += 1;
644                        Some(read_u8(data, o) ? as usize)
645                    }
646                    CBOR_MAP_16 => {
647                        *o += 1;
648                        Some(read_u16(data, o) ? as usize)
649                    }
650                    CBOR_MAP_32 => {
651                        *o += 1;
652                        Some(read_u32(data, o) ? as usize)
653                    }
654                    CBOR_MAP_64 => {
655                        *o += 1;
656                        Some(read_u32(data, o) ? as usize)
657                    }
658                    _ => return Ok(None)
659                }
660            };
661            Ok(v)
662        }
663        
664        fn decode_id(data: &[u8], o: &mut usize) -> Result<Option<LiveId>, LiveNodeFromCborError> {
665            // we expect a string OR a u64
666            if let Some(val) = decode_str(data, o) ? {
667                if let Ok(id) = LiveId::from_str_with_lut(val) {
668                    return Ok(Some(id))
669                }
670                else {
671                    return Err(LiveNodeFromCborError::LiveIdCollision)
672                }
673            }
674            else if let Some(v) = decode_u64(data, o) ? {
675                return Ok(Some(LiveId(v)))
676            }
677            Ok(None)
678        }
679        
680        struct StackItem {len: usize, count: usize, has_keys: bool}
681        
682        let mut stack = vec![StackItem {count: 0, len: 1, has_keys: false}];
683        let origin = LiveNodeOrigin::field();
684        let mut o = 0;
685        while o < data.len() {
686            
687            if stack.last().unwrap().count == stack.last().unwrap().len {
688                self.push(LiveNode {id: LiveId(0), origin, value: LiveValue::Close});
689                stack.pop();
690            }
691            
692            // ok lets read
693            let stack_item = stack.last_mut().unwrap();
694            let id = if stack_item.has_keys {
695                let id = decode_id(data, &mut o) ?;
696                if id.is_none() {return Err(LiveNodeFromCborError::ExpectedId)}
697                id.unwrap()
698            }
699            else {
700                LiveId(0)
701            };
702            
703            stack_item.count += 1;
704            
705            assert_len(o, 1, data) ?;
706            
707            if let Some(v) = decode_i64(data, &mut o) ? {
708                self.push(LiveNode {id, origin, value: LiveValue::Int64(v)});
709            }
710            else if let Some(v) = decode_str(data, &mut o) ? {
711                let value = if let Some(inline_str) = InlineString::from_str(v) {
712                    LiveValue::InlineString(inline_str)
713                }
714                else {
715                    LiveValue::String(Rc::new(v.to_string()))
716                };
717                self.push(LiveNode {id, origin, value});
718            }
719            else if let Some(len) = decode_array_len(data, &mut o) ? {
720                stack.push(StackItem {count: 0, len, has_keys: false});
721                self.push(LiveNode {id, origin, value: LiveValue::Array});
722            }
723            else if let Some(len) = decode_map_len(data, &mut o) ? {
724                // this COULD be a special type.
725                if len == 1 {
726                    let mut o1 = o;
727                    if let Some(s) = decode_str(data, &mut o1) ? {
728                        match s {
729                            "in" => { // its a vec
730                                return Err(LiveNodeFromCborError::NotImpl)
731                            }
732                            "as" => { // its a color
733                                return Err(LiveNodeFromCborError::NotImpl)
734                            }
735                            "if" => { // bare enum
736                                if let Some(variant) = decode_id(data, &mut o1) ? {
737                                    self.push(LiveNode {
738                                        id,
739                                        origin,
740                                        value: LiveValue::BareEnum(variant)
741                                    });
742                                    o = o1;
743                                    continue;
744                                }
745                                else {
746                                    return Err(LiveNodeFromCborError::ExpectedBareEnumString)
747                                }
748                            }
749                            "enum" => { // other enum
750                                return Err(LiveNodeFromCborError::NotImpl)
751                            }
752                            _ => ()
753                        }
754                    }
755                }
756                stack.push(StackItem {count: 0, len, has_keys: true});
757                self.push(LiveNode {id, origin, value: LiveValue::Object});
758            }
759            else {
760                match data[o] {
761                    CBOR_TRUE => {
762                        o += 1;
763                        self.push(LiveNode {id, origin, value: LiveValue::Bool(true)});
764                    }
765                    CBOR_FALSE => {
766                        o += 1;
767                        self.push(LiveNode {id, origin, value: LiveValue::Bool(false)});
768                    }
769                    CBOR_FLOAT32 => {
770                        o += 1;
771                        let value = LiveValue::Float32(read_f32(data, &mut o) ?);
772                        self.push(LiveNode {id, origin, value});
773                    }
774                    CBOR_FLOAT64 => {
775                        o += 1;
776                        let value = LiveValue::Float64(read_f64(data, &mut o) ?);
777                        self.push(LiveNode {id, origin, value});
778                    }
779                    CBOR_NULL => {
780                        o += 1;
781                        self.push(LiveNode {id, origin, value: LiveValue::None});
782                    },
783                    _ => {
784                        return Err(LiveNodeFromCborError::UnexpectedValue)
785                    }
786                }
787            };
788        }
789        // lets unwind the stack
790        while let Some(item) = stack.pop() {
791            if item.count != item.len {
792                return Err(LiveNodeFromCborError::StackNotClosed)
793            }
794        }
795        self.push(LiveNode {id: LiveId(0), origin, value: LiveValue::Close});
796        Ok(())
797    }
798}