swamp_script_core/
qck_des.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/script
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5use 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/// # Panics
15///
16#[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(); //SeqMap<Value, ValueRef>
102            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, // TODO: FIX hardcoded number
159                    });
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, // TODO: FIX hardcoded number
176                    });
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, // TODO: FIX hardcoded number
213                    });
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}