orientdb_client/common/protocol/v37/
serializer.rs1use super::super::buffer::OBuffer;
2use super::Protocol37;
3use crate::common::protocol::serializer::DocumentSerializer;
4use crate::common::types::document::ODocument;
5use crate::common::types::value::OValue;
6use crate::common::OrientResult;
7
8impl DocumentSerializer for Protocol37 {
9 fn encode_document(doc: &ODocument) -> OrientResult<OBuffer> {
10 let mut doc_buf = OBuffer::new();
11 encode_document(doc, &mut doc_buf)?;
12 Ok(doc_buf)
13 }
14}
15
16fn encode_document(doc: &ODocument, buf: &mut OBuffer) -> OrientResult<()> {
17 buf.write_string(doc.class_name())?;
18 buf.write_varint(doc.len() as i64)?;
19
20 for (k, v) in doc.iter() {
21 write_field(buf, k, v)?;
22 }
23 Ok(())
24}
25fn write_field<'a>(buf: &mut OBuffer, name: &'a str, value: &'a OValue) -> OrientResult<()> {
26 buf.write_string(name)?;
27
28 buf.put_i8(value.get_type_id())?;
29
30 write_value(buf, name, value)?;
31
32 Ok(())
33}
34
35fn write_value<'a>(buf: &mut OBuffer, owner: &'a str, value: &'a OValue) -> OrientResult<()> {
36 match value {
37 OValue::String(ref s) => buf.write_string(s),
38 OValue::Boolean(v) => {
39 buf.write_bool(*v)?;
40 Ok(())
41 }
42 OValue::I16(v) => buf.write_varint(i64::from(*v)),
43 OValue::I32(v) => buf.write_varint(i64::from(*v)),
44 OValue::I64(v) => buf.write_varint(*v),
45 OValue::Link(ref v) => {
46 buf.write_varint(i64::from(v.cluster))?;
47 buf.write_varint(v.position)?;
48 Ok(())
49 }
50 OValue::EmbeddedList(ref v) => {
51 buf.write_varint(v.len() as i64)?;
52
53 for (idx, elem) in v.iter().enumerate() {
54 buf.put_i8(elem.get_type_id())?;
55 write_value(buf, &format!("{}_{}", owner, idx), elem)?;
56 }
57
58 Ok(())
59 }
60 OValue::Document(ref doc) => {
61 encode_document(doc, buf)?;
62 Ok(())
63 }
64
65 OValue::LinkList(ref list) => {
66 buf.write_varint(list.links.len() as i64)?;
67
68 for link in list.links.iter() {
69 buf.write_varint(i64::from(link.cluster))?;
70 buf.write_varint(link.position)?;
71 }
72 Ok(())
73 }
74 OValue::EmbeddedMap(ref map) => {
75 buf.write_varint(map.len() as i64)?;
76 for (k, v) in map {
77 write_field(buf, k, v)?;
78 }
79 Ok(())
80 }
81 #[cfg(feature = "uuid")]
82 OValue::Uuid(ref uuid) => {
83 buf.write_string(&uuid.to_string())?;
84 Ok(())
85 }
86 _ => panic!("Field {} not supported", owner),
87 }?;
88 Ok(())
89}
90
91#[cfg(test)]
92mod tests {
93
94 use super::Protocol37;
95 use crate::common::protocol::deserializer::DocumentDeserializer;
96 use crate::common::protocol::serializer::DocumentSerializer;
97 use crate::common::types::document::ODocument;
98 use crate::common::types::rid::ORecordID;
99 use crate::common::types::value::{IntoOValue, LinkList, OValue};
100 use std::collections::HashMap;
101
102 #[test]
103 fn doc_ser_test() {
104 let mut doc = ODocument::new("Test");
105
106 doc.set("age", 20 as i16);
108 doc.set("year", 1983);
109 doc.set("balance", 10000 as i64);
110 doc.set("confirmed", true);
111 doc.set("name", String::from("John"));
112
113 doc.set("city", ORecordID::new(10, 0));
115
116 let map: HashMap<String, i32> = [("Norway", 100), ("Denmark", 50), ("Iceland", 10)]
117 .iter()
118 .map(|e| (String::from(e.0), e.1))
119 .collect();
120
121 let test_map = map.clone();
122
123 doc.set("tags", vec!["name", "happy", "friends"]);
124 doc.set("map", map);
125
126 let mut doc_embedded = ODocument::new("EmbeddedClass");
127 doc_embedded.set("name", "Foo");
128
129 let doc_embedded_cloned = doc_embedded.clone();
130
131 doc.set("embedded", doc_embedded);
132
133 let links: LinkList = vec![ORecordID::new(10, 10)].into();
134 doc.set("links", links);
135
136 let encoded = Protocol37::encode_document(&doc).unwrap();
137 let doc = Protocol37::decode_document(encoded.as_slice()).unwrap();
138
139 assert_eq!("Test", doc.class_name());
140 assert_eq!(Some(&OValue::I16(20)), doc.get_raw("age"));
141 assert_eq!(Some(&OValue::I32(1983)), doc.get_raw("year"));
142 assert_eq!(Some(&OValue::I64(10000)), doc.get_raw("balance"));
143 assert_eq!(Some(&OValue::Boolean(true)), doc.get_raw("confirmed"));
144 assert_eq!(
145 Some(&OValue::String(String::from("John"))),
146 doc.get_raw("name")
147 );
148
149 assert_eq!(
150 Some(&OValue::Link(ORecordID::new(10, 0))),
151 doc.get_raw("city")
152 );
153
154 let tags = OValue::EmbeddedList(vec![
155 OValue::String(String::from("name")),
156 OValue::String(String::from("happy")),
157 OValue::String(String::from("friends")),
158 ]);
159 assert_eq!(Some(&tags), doc.get_raw("tags"));
160
161 let embedded = OValue::EmbeddedMap(
162 test_map
163 .iter()
164 .map(|(k, v)| (k.clone(), v.into_ovalue()))
165 .collect(),
166 );
167
168 assert_eq!(Some(&embedded), doc.get_raw("map"));
169
170 assert_eq!(
171 Some(&OValue::Document(doc_embedded_cloned)),
172 doc.get_raw("embedded")
173 );
174
175 assert_eq!(
176 Some(&OValue::LinkList(vec![ORecordID::new(10, 10)].into())),
177 doc.get_raw("links")
178 );
179 }
180}