orientdb_client/common/protocol/v37/
deserializer.rs1use super::super::parser::{
2 parse_bool, parse_optimized_identity, parse_string_varint, parse_varint,
3};
4
5use super::Protocol37;
6use crate::common::protocol::constants;
7use crate::common::protocol::deserializer::DocumentDeserializer;
8use crate::common::types::bag::RidBag;
9use crate::common::types::document::ODocument;
10use crate::common::types::projection::Projection;
11use crate::common::types::value::OValue;
12
13use crate::{OrientError, OrientResult};
14
15use chrono::TimeZone;
16use chrono::Utc;
17use nom::IResult;
18
19use nom::number::streaming::{be_f32, be_f64, be_i64, be_i8, be_u8};
20use nom::{cond, do_parse, many_m_n, named, try_parse};
21use std::collections::HashMap;
22
23impl DocumentDeserializer for Protocol37 {
24 fn decode_document(input: &[u8]) -> OrientResult<ODocument> {
25 let (rm, doc) = parse_document(input)
26 .map_err(|e| OrientError::Decoder(format!("Error decoding document: {:?}", e)))?;
27 assert_eq!(rm.len(), 0);
28 Ok(doc)
29 }
30 fn decode_projection(input: &[u8]) -> OrientResult<Projection> {
31 let (rm, projection) = parse_projection(input)
32 .map_err(|e| OrientError::Decoder(format!("Error decoding projection: {:?}", e)))?;
33
34 assert_eq!(rm.len(), 0);
35 Ok(projection)
36 }
37}
38
39fn parse_document(input: &[u8]) -> IResult<&[u8], ODocument> {
40 let (remaining, class_name) = try_parse!(input, parse_string_varint);
41 let mut doc = ODocument::new(class_name);
42 let (mut remaining, fields) = try_parse!(remaining, parse_varint);
43 for _ in 0..fields {
44 let (rm, (field, value)) = parse_field(remaining, &|e| {
45 let (remaining, value) = try_parse!(e, parse_document);
46 Ok((remaining, OValue::Document(value)))
47 })?;
48 doc.set_raw(field, value);
49 remaining = rm;
50 }
51 Ok((remaining, doc))
52}
53
54fn parse_projection(input: &[u8]) -> IResult<&[u8], Projection> {
55 let (mut remaining, fields) = try_parse!(input, parse_varint);
56
57 let mut projection = Projection::default();
58 for _ in 0..fields {
59 let (rm, (field, value)) = parse_field(remaining, &|e| {
60 let (remaining, value) = try_parse!(e, parse_projection);
61 Ok((remaining, OValue::EmbeddedMap(value.take_map())))
62 })?;
63 projection.insert(field, value);
64 remaining = rm;
65 }
66 let (mut remaining, m_fields) = try_parse!(remaining, parse_varint);
67
68 for _ in 0..m_fields {
70 let (rm, (_field, _value)) = parse_field(remaining, &|e| {
71 let (remaining, value) = try_parse!(e, parse_projection);
72 Ok((remaining, OValue::EmbeddedMap(value.take_map())))
73 })?;
74 remaining = rm;
75 }
76
77 Ok((remaining, projection))
78}
79
80fn parse_value<'a, F>(remaining: &'a [u8], embedded: &F) -> IResult<&'a [u8], OValue>
81where
82 F: Fn(&[u8]) -> IResult<&[u8], OValue>,
83{
84 let (remaining, f_type) = try_parse!(remaining, be_i8);
85 let (remaining, value) = match f_type {
86 constants::BYTE => {
87 let (remaining, value) = try_parse!(remaining, be_i8);
88 (remaining, OValue::I8(value))
89 }
90 constants::BOOLEAN => {
91 let (remaining, value) = try_parse!(remaining, parse_bool);
92 (remaining, OValue::Boolean(value))
93 }
94 constants::LONG => {
95 let (remaining, value) = try_parse!(remaining, parse_varint);
96 (remaining, OValue::I64(value))
97 }
98 constants::INTEGER => {
99 let (remaining, value) = try_parse!(remaining, parse_varint);
100 (remaining, OValue::I32(value as i32))
101 }
102 constants::SHORT => {
103 let (remaining, value) = try_parse!(remaining, parse_varint);
104 (remaining, OValue::I16(value as i16))
105 }
106 constants::FLOAT => {
107 let (remaining, value) = try_parse!(remaining, be_f32);
108 (remaining, OValue::F32(value))
109 }
110 constants::DOUBLE => {
111 let (remaining, value) = try_parse!(remaining, be_f64);
112 (remaining, OValue::F64(value))
113 }
114 constants::STRING => {
115 let (remaining, value) = try_parse!(remaining, parse_string_varint);
116 (remaining, OValue::String(value))
117 }
118 constants::LINK => {
119 let (remaining, value) = try_parse!(remaining, parse_optimized_identity);
120 (remaining, OValue::Link(value))
121 }
122 constants::EMBEDDED => embedded(remaining)?,
123 constants::LINKLIST | constants::LINKSET => {
124 let (mut remaining, size) = try_parse!(remaining, parse_varint);
125 let mut links = Vec::new();
126 for _ in 0..size {
127 let (rm, rid) = try_parse!(remaining, parse_optimized_identity);
128 remaining = rm;
129 links.push(rid);
130 }
131 (remaining, OValue::LinkList(links.into()))
132 }
133 constants::EMBEDDEDLIST | constants::EMBEDDEDSET => {
134 let (mut remaining, size) = try_parse!(remaining, parse_varint);
135 let mut elements = Vec::new();
136 for _ in 0..size {
137 let (rm, elem) = parse_value(remaining, embedded)?;
138 remaining = rm;
139 elements.push(elem)
140 }
141 (remaining, OValue::EmbeddedList(elements))
142 }
143 constants::EMBEDDEDMAP => {
144 let (mut remaining, size) = try_parse!(remaining, parse_varint);
145 let mut elements = HashMap::new();
146 for _ in 0..size {
147 let (rm, (k, v)) = parse_field(remaining, embedded)?;
148 remaining = rm;
149 elements.insert(k, v);
150 }
151 (remaining, OValue::EmbeddedMap(elements))
152 }
153 constants::DATE => {
154 let (remaining, timestamp) = try_parse!(remaining, parse_varint);
155 (
156 remaining,
157 OValue::Date(Utc.timestamp(timestamp * 86400, 0).date()),
158 )
159 }
160 constants::DATETIME => {
161 let (remaining, timestamp) = try_parse!(remaining, parse_varint);
162 (
163 remaining,
164 OValue::DateTime(
165 Utc.timestamp(timestamp / 1000, (timestamp % 1000) as u32 * 1_000_000),
166 ),
167 )
168 }
169 constants::LINKBAG => {
170 let (remaining, (embedded, tree)) = try_parse!(remaining, parse_bags);
172 let bag = embedded.unwrap_or_else(|| tree.expect("Cannot find tree or embedded bags"));
173 (remaining, OValue::RidBag(bag))
174 }
175 constants::NULL => (remaining, OValue::Null),
176 _ => panic!("Unsupported field type {}", f_type),
177 };
178
179 Ok((remaining, value))
180}
181
182fn parse_field<'a, F>(remaining: &'a [u8], embedded: &F) -> IResult<&'a [u8], (String, OValue)>
183where
184 F: Fn(&[u8]) -> IResult<&[u8], OValue>,
185{
186 let (remaining, name) = try_parse!(remaining, parse_string_varint);
187 let (remaining, value) = parse_value(remaining, embedded)?;
188 Ok((remaining, (name, value)))
189}
190
191named!(pub parse_bags<&[u8],(Option<RidBag>,Option<RidBag>)>,
198 do_parse!(
199 _uuid1 : be_i64 >>
200 _uuid2 : be_i64 >>
201 bag_type : be_u8 >>
202 embedded : cond!(bag_type == 1,parse_bags_embedded ) >>
203 tree : cond!(bag_type == 2,parse_bags_tree ) >>
204 (embedded,tree)
205 )
206);
207
208named!(pub parse_bags_embedded<&[u8],RidBag>,
209 do_parse!(
210 size : parse_varint >>
211 bags : many_m_n!(0 as usize ,size as usize,parse_optimized_identity) >>
212 (RidBag::Embedded(bags))
213 )
214);
215
216named!(pub parse_bags_tree<&[u8],RidBag>,
218 do_parse!(
219 _file_id : parse_varint >>
220 _page_index : parse_varint >>
221 _page_offset : parse_varint >>
222 bag_size : parse_varint >>
223 _changes_size : parse_varint >>
224 (RidBag::Tree(bag_size as i32))
225 )
226);