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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use std::io::{Read, Seek};
use crate::error::TychoResult;
use crate::partial::reader::PartialReader;
use crate::partial::types::{PartialStruct, PartialList, PartialMap, PartialArray, PartialCompression};
use crate::read::element::read_element_ident;
use crate::read::length::read_length;
use crate::read::string::read_tstring;
use crate::read::value::{read_value, read_value_ident};
use crate::types::ident::{ElementIdent, ValueIdent};
use crate::Value;
#[derive(Debug, Clone)]
pub enum PartialElement {
Unit,
Value(Value),
Option(Option<Box<PartialElement>>),
Variant(String, Box<PartialElement>),
Struct(PartialStruct),
List(PartialList),
Map(PartialMap),
Array(PartialArray),
Compression(PartialCompression),
}
pub fn read_partial_element<R: Read + Seek>(reader: &mut PartialReader<R>) -> TychoResult<PartialElement> {
let ident = read_element_ident(reader)?;
match ident {
ElementIdent::Unit => Ok(PartialElement::Unit),
ElementIdent::Value => {
let prefix = read_value_ident(reader)?;
let value = read_value(reader, &prefix)?;
Ok(PartialElement::Value(value))
},
ElementIdent::None => Ok(PartialElement::Option(None)),
ElementIdent::Some => read_partial_element(reader),
ElementIdent::Variant => {
let name = read_tstring(reader)?;
let value =read_partial_element(reader)?;
Ok(PartialElement::Variant(name, Box::new(value)))
}
ElementIdent::Struct => {
let size = read_length(reader)? as u64;
let pos = reader.pointer.clone();
reader.jump(&size)?;
Ok(PartialElement::Struct(PartialStruct::new(reader.pointer(pos, size), 0, ())))
},
ElementIdent::List => {
let size = read_length(reader)? as u64;
let pos = reader.pointer.clone();
reader.jump(&size)?;
Ok(PartialElement::List(PartialList::new(reader.pointer(pos, size), 0, ())))
},
ElementIdent::Array => {
let array_type = read_value_ident(reader)?;
if array_type == ValueIdent::Null {
return Ok(PartialElement::Array(PartialArray::empty(reader.empty_pointer(),array_type)))
}
let size = read_length(reader)? as u64;
let pos = reader.pointer.clone();
reader.jump(&size)?;
Ok(PartialElement::Array(PartialArray::new(reader.pointer(pos, size), 0, array_type)))
},
ElementIdent::Map => {
let key_type = read_value_ident(reader)?;
if key_type == ValueIdent::Null {
return Ok(PartialElement::Map(PartialMap::empty(reader.empty_pointer(), key_type)))
}
let size = read_length(reader)? as u64;
let pos = reader.pointer.clone();
reader.jump(&size)?;
Ok(PartialElement::Map(PartialMap::new(reader.pointer(pos, size), 0, key_type)))
},
ElementIdent::Compression => {
let size = read_length(reader)? as u64;
let pos = reader.pointer.clone();
reader.jump(&size)?;
Ok(PartialElement::Compression(PartialCompression::new(reader.pointer(pos, size))))
}
}
}