1use serde::{Deserialize, Serialize};
2use std::cell::RefCell;
3use std::collections::{HashMap, HashSet, hash_map::Entry};
4use std::rc::Rc;
5
6use crate::{Type, UpValue, Value};
7
8pub type FlatValueID = usize;
10
11#[derive(Clone, Debug, Deserialize, Serialize)]
14pub enum FlatValue {
15 Field(String),
16 Ty(Type),
17 Blob(usize),
18 Instance(usize, HashMap<String, FlatValueID>),
19 Tuple(Vec<FlatValueID>),
20 List(Vec<FlatValueID>),
21 Set(HashSet<FlatValueID>),
22 Dict(HashMap<FlatValueID, FlatValueID>),
23 Float(f64),
24 Int(i64),
25 Bool(bool),
26 String(String),
27 Function(Vec<FlatUpValue>, Type, usize),
28 ExternFunction(usize),
29 Unknown,
30 Nil,
31}
32
33pub type FlatValuePack = Vec<FlatValue>;
35
36impl FlatValue {
37 pub fn pack(value: &Value) -> FlatValuePack {
42 let mut pack = Vec::new();
43 let mut seen = HashMap::new();
44 Self::pack_inner(value, &mut pack, &mut seen);
45 pack
46 }
47
48 fn pack_inner(value: &Value, pack: &mut FlatValuePack, seen: &mut HashMap<usize, FlatValueID>) -> FlatValueID {
50 let id = pack.len();
51 match seen.entry(value.unique_id()) {
52 Entry::Occupied(entry) => { return *entry.get(); }
53 Entry::Vacant(entry) => { entry.insert(id); }
54 }
55 pack.push(FlatValue::Nil);
56
57 let val = match value {
58 Value::Field(s) => FlatValue::Field(s.into()),
59 Value::Ty(ty) => FlatValue::Ty(ty.clone()),
60 Value::Blob(slot) => FlatValue::Blob(*slot),
61 Value::Instance(ty_slot, values) => FlatValue::Instance(
62 *ty_slot,
63 values
64 .borrow()
65 .iter()
66 .map(|(field, value)| (field.clone(), Self::pack_inner(value, pack, seen)))
67 .collect(),
68 ),
69 Value::Tuple(values) => FlatValue::Tuple(
70 values.iter().map(|value| Self::pack_inner(value, pack, seen)).collect(),
71 ),
72 Value::List(values) => FlatValue::List(
73 values.borrow().iter().map(|value| Self::pack_inner(value, pack, seen)).collect(),
74 ),
75 Value::Set(values) => FlatValue::Set(
76 values.borrow().iter().map(|value| Self::pack_inner(value, pack, seen)).collect(),
77 ),
78 Value::Dict(values) => FlatValue::Dict(
79 values
80 .borrow()
81 .iter()
82 .map(|(v1, v2)| (Self::pack_inner(v1, pack, seen), Self::pack_inner(v2, pack, seen)))
83 .collect(),
84 ),
85 Value::Float(f) => FlatValue::Float(*f),
86 Value::Int(i) => FlatValue::Int(*i),
87 Value::Bool(b) => FlatValue::Bool(*b),
88 Value::String(s) => FlatValue::String(String::clone(s)),
89 Value::Function(captured, ty, slot) => FlatValue::Function(
90 captured
91 .iter()
92 .map(|upvalue| FlatUpValue { slot: upvalue.borrow().slot, value: Self::pack_inner(&upvalue.borrow().value, pack, seen) })
93 .collect(),
94 ty.clone(),
95 *slot,
96 ),
97 Value::ExternFunction(slot) => FlatValue::ExternFunction(*slot),
98 Value::Unknown => FlatValue::Unknown,
99 Value::Nil => FlatValue::Nil,
100 Value::Union(_) => {
101 unreachable!("Cannot send union values over the network");
102 }
103 };
104 pack[id] = val;
105 id
106 }
107
108 fn partial_unpack(value: FlatValue) -> Value {
111 match value {
112 FlatValue::Field(s) => Value::Field(s),
113 FlatValue::Ty(ty) => Value::Ty(ty),
114 FlatValue::Blob(slot) => Value::Blob(slot),
115 FlatValue::Instance(ty_slot, _) => Value::Instance(
116 ty_slot,
117 Rc::new(RefCell::new(HashMap::new())),
118 ),
119 FlatValue::Tuple(_) => Value::Tuple(Rc::new(Vec::new())),
121 FlatValue::List(_) => Value::List(Rc::new(RefCell::new(Vec::new()))),
122 FlatValue::Set(_) => Value::Set(Rc::new(RefCell::new(HashSet::new()))),
123 FlatValue::Dict(_) => Value::Dict(Rc::new(RefCell::new(HashMap::new()))),
124 FlatValue::Float(f) => Value::Float(f),
125 FlatValue::Int(i) => Value::Int(i),
126 FlatValue::Bool(b) => Value::Bool(b),
127 FlatValue::String(s) => Value::String(Rc::new(s)),
128 FlatValue::Function(_, ty, slot) => Value::Function(
130 Rc::new(Vec::new()),
131 ty,
132 slot,
133 ),
134 FlatValue::ExternFunction(slot) => Value::ExternFunction(slot),
135 FlatValue::Unknown => Value::Unknown,
136 FlatValue::Nil => Value::Nil,
137 }
138 }
139
140 pub fn unpack(pack: &FlatValuePack) -> Value {
144 let mut mapping: Vec<Value> = pack.iter().cloned().map(Self::partial_unpack).collect();
147 for (i, x) in mapping.iter().enumerate() {
148 match (&pack[i], x) {
149 (FlatValue::Tuple(flat), Value::Tuple(values)) => {
150 let values = unsafe { (Rc::as_ptr(values) as *mut Vec<Value>).as_mut() }.unwrap();
154 for id in flat {
155 values.push(mapping[*id].clone());
156 }
157 }
158 (FlatValue::Function(flat, _, _), Value::Function(values, _, _)) => {
159 let values = unsafe { (Rc::as_ptr(values) as *mut Vec<Rc<RefCell<UpValue>>>).as_mut() }.unwrap();
161 for up in flat {
162 values.push(Rc::new(RefCell::new(UpValue { slot: up.slot, value: mapping[up.value].clone() })));
163 }
164 }
165 (FlatValue::Instance(_, flat), Value::Instance(_, values)) => {
166 let mut values = values.borrow_mut();
167 for (key, id) in flat {
168 values.insert(key.clone(), mapping[*id].clone());
169 }
170 }
171 (FlatValue::List(flat), Value::List(values)) => {
172 let mut values = values.borrow_mut();
173 for id in flat {
174 values.push(mapping[*id].clone());
175 }
176 }
177 (FlatValue::Set(flat), Value::Set(values)) => {
178 let mut values = values.borrow_mut();
179 for id in flat {
180 values.insert(mapping[*id].clone());
181 }
182 }
183 (FlatValue::Dict(flat), Value::Dict(values)) => {
184 let mut values = values.borrow_mut();
185 for (key_id, value_id) in flat {
186 values.insert(mapping[*key_id].clone(), mapping[*value_id].clone());
187 }
188 }
189 _ => {}
190 }
191 }
192
193 mapping.remove(0)
194 }
195}
196
197#[derive(Clone, Debug, Deserialize, Serialize)]
199pub struct FlatUpValue {
200 slot: usize,
201 value: FlatValueID,
202}
203