swamp_script_core/
qck_des.rs1use crate::extra::{SparseValueId, SparseValueMap};
6use crate::prelude::Value;
7use crate::value::{QuickDeserialize, RustType, SPARSE_ID_TYPE_ID, SPARSE_TYPE_ID};
8use fixed32::Fp;
9use seq_map::SeqMap;
10use std::cell::RefCell;
11use std::rc::Rc;
12use swamp_script_semantic::{ResolvedEnumVariantContainerType, ResolvedRustType, ResolvedType};
13
14#[inline]
17#[allow(clippy::too_many_lines)]
18#[must_use]
19pub fn quick_deserialize(resolved_type: &ResolvedType, buf: &[u8], depth: usize) -> (Value, usize) {
20 let (val, octet_size) = match resolved_type {
21 ResolvedType::Int => {
22 let i = i32::from_le_bytes(buf[0..4].try_into().expect("REASON"));
23 (Value::Int(i), 4)
24 }
25
26 ResolvedType::Float => {
27 let i = i32::from_le_bytes(buf[0..4].try_into().expect("couldn't convert to Fp"));
28 (Value::Float(Fp::from_raw(i)), 4)
29 }
30 ResolvedType::String => {
31 let octet_len =
32 u16::from_le_bytes(buf[0..2].try_into().expect("could not convert strlen"));
33 let str =
34 String::from_utf8(buf[2..2 + octet_len as usize].to_owned()).expect("utf8 error");
35 (Value::String(str), (octet_len + 2) as usize)
36 }
37 ResolvedType::Bool => (Value::Bool(buf[0] != 0), 1),
38 ResolvedType::Unit => (Value::Unit, 0),
39 ResolvedType::Array(array_type_ref) => {
40 let mut offset = 0;
41 let count = u16::from_le_bytes(
42 buf[offset..offset + 2]
43 .try_into()
44 .expect("should work with u16"),
45 );
46 offset += 2;
47
48 let item_ref = &array_type_ref.item_type;
49
50 let mut values = Vec::new();
51 for _index in 0..count {
52 let (value, item_octet_size) =
53 quick_deserialize(item_ref, &buf[offset..], depth + 1);
54
55 offset += item_octet_size;
56
57 values.push(Rc::new(RefCell::new(value)));
58 }
59
60 (Value::Array(array_type_ref.clone(), values), offset)
61 }
62 ResolvedType::Tuple(tuple_type_ref) => {
63 let mut offset = 0;
64 let mut values = Vec::new();
65 for tuple_item_type in &tuple_type_ref.0 {
66 let (value, item_octet_size) =
67 quick_deserialize(tuple_item_type, &buf[offset..], depth + 1);
68 values.push(Rc::new(RefCell::new(value)));
69 offset += item_octet_size;
70 }
71 (Value::Tuple(tuple_type_ref.clone(), values), offset)
72 }
73 ResolvedType::Struct(struct_type_ref) => {
74 let mut values = Vec::new();
75 let mut offset = 0;
76 for struct_field_type in struct_type_ref
77 .borrow()
78 .anon_struct_type
79 .defined_fields
80 .values()
81 {
82 let (value, octet_size) =
83 quick_deserialize(&struct_field_type.field_type, &buf[offset..], depth + 1);
84 values.push(Rc::new(RefCell::new(value)));
85 offset += octet_size;
86 }
87 (Value::Struct(struct_type_ref.clone(), values), offset)
88 }
89 ResolvedType::Map(map_type_ref) => {
90 let mut offset = 0;
91 let count = u16::from_le_bytes(
92 buf[offset..offset + 2]
93 .try_into()
94 .expect("should work with u16"),
95 );
96 offset += 2;
97
98 let key_type = &map_type_ref.key_type;
99 let value_type = &map_type_ref.value_type;
100
101 let mut seq_map = SeqMap::new(); for _map_index in 0..count {
103 let (key_val, key_octet_size) =
104 quick_deserialize(key_type, &buf[offset..], depth + 1);
105 offset += key_octet_size;
106
107 let (value_val, value_octet_size) =
108 quick_deserialize(value_type, &buf[offset..], depth + 1);
109 offset += value_octet_size;
110
111 let value_ref = Rc::new(RefCell::new(value_val));
112
113 seq_map
114 .insert(key_val, value_ref)
115 .expect("should work to insert");
116 }
117 (Value::Map(map_type_ref.clone(), seq_map), offset)
118 }
119 ResolvedType::Enum(enum_type) => {
120 let mut offset = 0;
121 let enum_lookup_index = buf[offset];
122 offset += 1;
123 assert!(enum_lookup_index < 8);
124
125 let borrowed_enum = enum_type.borrow();
126
127 let variant_type = borrowed_enum
128 .get_variant_from_index(enum_lookup_index as usize)
129 .expect("should be able to find variant");
130
131 let val = match &variant_type.data {
132 ResolvedEnumVariantContainerType::Struct(_) => {
133 todo!("struct containers not done yet")
134 }
135 ResolvedEnumVariantContainerType::Tuple(tuple_type_ref) => {
136 let mut vals_in_order = Vec::new();
137 for tuple_type in &tuple_type_ref.fields_in_order {
138 let (tuple_value, tuple_octet_size) =
139 quick_deserialize(tuple_type, &buf[offset..], depth + 1);
140 vals_in_order.push(tuple_value);
141 offset += tuple_octet_size;
142 }
143 Value::EnumVariantTuple(tuple_type_ref.clone(), vals_in_order)
144 }
145 ResolvedEnumVariantContainerType::Nothing => {
146 offset += 0;
147 Value::EnumVariantSimple(variant_type.clone())
148 }
149 };
150
151 (val, offset)
152 }
153 ResolvedType::Generic(base_type, type_parameters) => {
154 if let ResolvedType::RustType(found_rust_type) = &**base_type {
155 if found_rust_type.number == SPARSE_TYPE_ID {
156 let sparse_type_id_rust_type = Rc::new(ResolvedRustType {
157 type_name: "SparseId".to_string(),
158 number: SPARSE_ID_TYPE_ID, });
160
161 let value_type = &type_parameters[0];
162
163 let (internal_map, sparse_value_map_octet_size) =
164 SparseValueMap::quick_deserialize(
165 sparse_type_id_rust_type,
166 value_type.clone(),
167 buf,
168 );
169
170 let wrapped_internal_map: Rc<RefCell<Box<dyn RustType>>> =
171 Rc::new(RefCell::new(Box::new(internal_map)));
172
173 let sparse_collection_rust_type = Rc::new(ResolvedRustType {
174 type_name: "Sparse".to_string(),
175 number: SPARSE_TYPE_ID, });
177
178 (
179 Value::RustValue(sparse_collection_rust_type, wrapped_internal_map),
180 sparse_value_map_octet_size,
181 )
182 } else {
183 panic!("unknown generic type");
184 }
185 } else {
186 panic!("unknown generic type")
187 }
188 }
189 ResolvedType::Function(_) => {
190 panic!("can not serialize function")
191 }
192 ResolvedType::Iterable(_) => {
193 panic!("can not serialize iterables")
194 }
195 ResolvedType::Optional(optional_type_ref) => {
196 let mut offset = 0;
197 let has_some = buf[0] != 0;
198 offset += 1;
199 if has_some {
200 let (v, octet_size) = quick_deserialize(optional_type_ref, &buf[1..], depth + 1);
201 offset += octet_size;
202 (Value::Option(Some(Rc::new(RefCell::new(v)))), offset)
203 } else {
204 (Value::Option(None), offset)
205 }
206 }
207 ResolvedType::RustType(rust_type_ref) => {
208 match rust_type_ref.number {
209 SPARSE_ID_TYPE_ID => {
210 let sparse_id_rust_type = Rc::new(ResolvedRustType {
211 type_name: "SparseId".to_string(),
212 number: SPARSE_ID_TYPE_ID, });
214
215 let (sparse_value_id, octet_size) = SparseValueId::quick_deserialize(buf);
216 (
217 {
218 let boxed_sparse_value_id: Rc<RefCell<Box<dyn RustType>>> =
219 Rc::new(RefCell::new(Box::new(sparse_value_id)));
220 Value::RustValue(sparse_id_rust_type, boxed_sparse_value_id)
221 },
222 octet_size,
223 )
224 }
225 _ => panic!("can not deserialize rust types {}", rust_type_ref.type_name),
226 }
227 }
228 ResolvedType::Any => {
229 panic!("can not deserialize any");
230 }
231 };
232
233 (val, octet_size)
234}