1use super::error::{Error, Result};
4use super::types;
5#[cfg(feature = "value")]
6use super::types::value::IDLValue;
7use super::types::{internal::Opcode, Field, Type, TypeEnv, TypeInner};
8use byteorder::{LittleEndian, WriteBytesExt};
9use leb128::write::{signed as sleb128_encode, unsigned as leb128_encode};
10use std::collections::{BTreeMap, TryReserveError};
11use std::io;
12use std::vec::Vec;
13
14#[derive(Default)]
16pub struct IDLBuilder {
17 type_ser: TypeSerialize,
18 value_ser: ValueSerializer,
19}
20
21impl IDLBuilder {
22 pub fn new() -> Self {
23 types::internal::env_clear();
27 IDLBuilder {
28 type_ser: TypeSerialize::new(),
29 value_ser: ValueSerializer::new(),
30 }
31 }
32 pub fn arg<'a, T: types::CandidType>(&'a mut self, value: &T) -> Result<&'a mut Self> {
33 self.type_ser.push_type(&T::ty())?;
34 value.idl_serialize(&mut self.value_ser)?;
35 Ok(self)
36 }
37 #[cfg_attr(docsrs, doc(cfg(feature = "value")))]
38 #[cfg(feature = "value")]
39 pub fn value_arg<'a>(&'a mut self, value: &IDLValue) -> Result<&'a mut Self> {
40 use super::CandidType;
41 self.type_ser.push_type(&value.value_ty())?;
42 value.idl_serialize(&mut self.value_ser)?;
43 Ok(self)
44 }
45 #[cfg_attr(docsrs, doc(cfg(feature = "value")))]
46 #[cfg(feature = "value")]
47 pub fn value_arg_with_type<'a>(
50 &'a mut self,
51 value: &IDLValue,
52 env: &TypeEnv,
53 t: &Type,
54 ) -> Result<&'a mut Self> {
55 use super::CandidType;
56 let env = self.type_ser.env.merge(env)?;
57 let v = value.annotate_type(true, env, t)?;
58 self.type_ser.push_type(t)?;
59 v.idl_serialize(&mut self.value_ser)?;
60 Ok(self)
61 }
62 pub fn serialize<W: io::Write>(&mut self, mut writer: W) -> Result<()> {
63 writer.write_all(b"DIDL")?;
64 self.type_ser.serialize()?;
65 writer.write_all(self.type_ser.get_result())?;
66 writer.write_all(self.value_ser.get_result())?;
67 Ok(())
68 }
69 pub fn serialize_to_vec(&mut self) -> Result<Vec<u8>> {
70 let mut vec = Vec::new();
71 self.serialize(&mut vec)?;
72 Ok(vec)
73 }
74 pub fn try_reserve_value_serializer_capacity(
77 &mut self,
78 additional: usize,
79 ) -> std::result::Result<(), TryReserveError> {
80 self.value_ser.try_reserve(additional)
81 }
82}
83
84#[derive(Default)]
86pub struct ValueSerializer {
87 value: Vec<u8>,
88}
89
90impl ValueSerializer {
91 #[inline]
93 pub fn new() -> Self {
94 ValueSerializer { value: Vec::new() }
95 }
96 pub fn get_result(&self) -> &[u8] {
97 &self.value
98 }
99 #[doc(hidden)]
100 pub fn write_leb128(&mut self, value: u64) -> Result<()> {
101 leb128_encode(&mut self.value, value)?;
102 Ok(())
103 }
104 #[doc(hidden)]
105 pub fn write(&mut self, bytes: &[u8]) -> Result<()> {
106 use std::io::Write;
107 self.value.write_all(bytes)?;
108 Ok(())
109 }
110 #[doc(hidden)]
111 pub fn try_reserve(&mut self, additional: usize) -> std::result::Result<(), TryReserveError> {
112 self.value.try_reserve(additional)
113 }
114}
115
116macro_rules! serialize_num {
117 ($name:ident, $ty:ty, $($method:tt)*) => {
118 paste::item! {
119 fn [<serialize_ $name>](self, v: $ty) -> Result<()> {
120 self.value.$($method)*(v)?;
121 Ok(())
122 }
123 }
124 };
125}
126
127impl<'a> types::Serializer for &'a mut ValueSerializer {
128 type Error = Error;
129 type Compound = Compound<'a>;
130 fn serialize_bool(self, v: bool) -> Result<()> {
131 self.write(&[v as u8])?;
132 Ok(())
133 }
134 #[cfg(feature = "bignum")]
135 fn serialize_int(self, v: &crate::Int) -> Result<()> {
136 v.encode(&mut self.value)
137 }
138 #[cfg(feature = "bignum")]
139 fn serialize_nat(self, v: &crate::Nat) -> Result<()> {
140 v.encode(&mut self.value)
141 }
142 fn serialize_i128(self, v: i128) -> Result<()> {
143 crate::types::leb128::encode_int(&mut self.value, v)
144 }
145 fn serialize_u128(self, v: u128) -> Result<()> {
146 crate::types::leb128::encode_nat(&mut self.value, v)
147 }
148 serialize_num!(nat8, u8, write_u8);
149 serialize_num!(nat16, u16, write_u16::<LittleEndian>);
150 serialize_num!(nat32, u32, write_u32::<LittleEndian>);
151 serialize_num!(nat64, u64, write_u64::<LittleEndian>);
152
153 serialize_num!(int8, i8, write_i8);
154 serialize_num!(int16, i16, write_i16::<LittleEndian>);
155 serialize_num!(int32, i32, write_i32::<LittleEndian>);
156 serialize_num!(int64, i64, write_i64::<LittleEndian>);
157
158 serialize_num!(float32, f32, write_f32::<LittleEndian>);
159 serialize_num!(float64, f64, write_f64::<LittleEndian>);
160
161 fn serialize_text(self, v: &str) -> Result<()> {
162 let buf = v.as_bytes();
163 self.write_leb128(buf.len() as u64)?;
164 self.value.extend_from_slice(buf);
165 Ok(())
166 }
167 fn serialize_null(self, _v: ()) -> Result<()> {
168 Ok(())
169 }
170 fn serialize_empty(self) -> Result<()> {
171 Err(Error::msg("cannot encode empty type"))
172 }
173 fn serialize_principal(self, blob: &[u8]) -> Result<()> {
174 self.write(&[1])?;
175 self.write_leb128(blob.len() as u64)?;
176 self.write(blob)?;
177 Ok(())
178 }
179 fn serialize_function(self, blob: &[u8], meth: &str) -> Result<()> {
180 self.write(&[1])?;
181 self.serialize_principal(blob)?;
182 self.serialize_text(meth)
183 }
184 fn serialize_option<T>(self, v: Option<&T>) -> Result<()>
185 where
186 T: super::CandidType + ?Sized,
187 {
188 match v {
189 None => {
190 self.write_leb128(0)?;
191 Ok(())
192 }
193 Some(v) => {
194 self.write_leb128(1)?;
195 v.idl_serialize(self)
196 }
197 }
198 }
199 fn serialize_variant(self, index: u64) -> Result<Self::Compound> {
200 self.write_leb128(index)?;
201 Ok(Self::Compound { ser: self })
202 }
203 fn serialize_struct(self) -> Result<Self::Compound> {
204 Ok(Self::Compound { ser: self })
205 }
206 fn serialize_vec(self, len: usize) -> Result<Self::Compound> {
207 self.write_leb128(len as u64)?;
208 Ok(Self::Compound { ser: self })
209 }
210 fn serialize_blob(self, blob: &[u8]) -> Result<()> {
211 self.write_leb128(blob.len() as u64)?;
212 self.write(blob)?;
213 Ok(())
214 }
215}
216
217pub struct Compound<'a> {
218 ser: &'a mut ValueSerializer,
219}
220impl types::Compound for Compound<'_> {
221 type Error = Error;
222 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
223 where
224 T: types::CandidType + ?Sized,
225 {
226 value.idl_serialize(&mut *self.ser)?;
227 Ok(())
228 }
229 fn serialize_blob(&mut self, blob: &[u8]) -> Result<()> {
230 use crate::types::Serializer;
231 self.ser.serialize_blob(blob)
232 }
233}
234
235#[derive(Default)]
237pub struct TypeSerialize {
238 type_table: Vec<Vec<u8>>,
239 type_map: BTreeMap<Type, i32>,
240 env: TypeEnv,
241 args: Vec<Type>,
242 result: Vec<u8>,
243}
244
245impl TypeSerialize {
246 #[inline]
247 pub fn new() -> Self {
248 TypeSerialize {
249 type_table: Vec::new(),
250 type_map: BTreeMap::new(),
251 env: TypeEnv::new(),
252 args: Vec::new(),
253 result: Vec::new(),
254 }
255 }
256 pub fn get_result(&self) -> &[u8] {
257 &self.result
258 }
259 #[inline]
260 fn build_type(&mut self, t: &Type) -> Result<()> {
261 if self.type_map.contains_key(t) {
262 return Ok(());
263 }
264 let actual_type = if let TypeInner::Var(id) = t.as_ref() {
265 self.env.rec_find_type(id)?
266 } else {
267 t
268 }
269 .clone();
270 if types::internal::is_primitive(&actual_type) {
271 return Ok(());
272 }
273 let idx = self.type_table.len();
286 self.type_map.insert(t.clone(), idx as i32);
287 self.type_table.push(Vec::new());
288 let mut buf = Vec::new();
289 match actual_type.as_ref() {
290 TypeInner::Opt(ref ty) => {
291 self.build_type(ty)?;
292 sleb128_encode(&mut buf, Opcode::Opt as i64)?;
293 self.encode(&mut buf, ty)?;
294 }
295 TypeInner::Vec(ref ty) => {
296 self.build_type(ty)?;
297 sleb128_encode(&mut buf, Opcode::Vec as i64)?;
298 self.encode(&mut buf, ty)?;
299 }
300 TypeInner::Record(fs) => {
301 for Field { ty, .. } in fs {
302 self.build_type(ty)?;
303 }
304
305 sleb128_encode(&mut buf, Opcode::Record as i64)?;
306 leb128_encode(&mut buf, fs.len() as u64)?;
307 for Field { id, ty } in fs {
308 leb128_encode(&mut buf, u64::from(id.get_id()))?;
309 self.encode(&mut buf, ty)?;
310 }
311 }
312 TypeInner::Variant(fs) => {
313 for Field { ty, .. } in fs {
314 self.build_type(ty)?;
315 }
316
317 sleb128_encode(&mut buf, Opcode::Variant as i64)?;
318 leb128_encode(&mut buf, fs.len() as u64)?;
319 for Field { id, ty } in fs {
320 leb128_encode(&mut buf, u64::from(id.get_id()))?;
321 self.encode(&mut buf, ty)?;
322 }
323 }
324 TypeInner::Service(ref ms) => {
325 for (_, ty) in ms {
326 self.build_type(ty)?;
327 }
328 sleb128_encode(&mut buf, Opcode::Service as i64)?;
329 leb128_encode(&mut buf, ms.len() as u64)?;
330 for (id, ty) in ms {
331 let name = id.as_bytes();
332 leb128_encode(&mut buf, name.len() as u64)?;
333 buf.extend_from_slice(name);
334 self.encode(&mut buf, ty)?;
335 }
336 }
337 TypeInner::Func(ref func) => {
338 for ty in func.args.iter().chain(func.rets.iter()) {
339 self.build_type(ty)?;
340 }
341 for ty in &func.rets {
342 self.build_type(ty)?;
343 }
344 sleb128_encode(&mut buf, Opcode::Func as i64)?;
345 leb128_encode(&mut buf, func.args.len() as u64)?;
346 for ty in &func.args {
347 self.encode(&mut buf, ty)?;
348 }
349 leb128_encode(&mut buf, func.rets.len() as u64)?;
350 for ty in &func.rets {
351 self.encode(&mut buf, ty)?;
352 }
353 leb128_encode(&mut buf, func.modes.len() as u64)?;
354 for m in &func.modes {
355 use crate::types::FuncMode;
356 let m = match m {
357 FuncMode::Query => 1,
358 FuncMode::Oneway => 2,
359 FuncMode::CompositeQuery => 3,
360 };
361 sleb128_encode(&mut buf, m)?;
362 }
363 }
364 _ => unreachable!(),
365 };
366 self.type_table[idx] = buf;
367 Ok(())
368 }
369 #[doc(hidden)]
370 pub fn push_type(&mut self, t: &Type) -> Result<()> {
371 self.args.push(t.clone());
372 self.build_type(t)
373 }
374 fn encode(&self, buf: &mut Vec<u8>, t: &Type) -> Result<()> {
375 if let TypeInner::Var(id) = t.as_ref() {
376 let actual_type = self.env.rec_find_type(id)?;
377 if types::internal::is_primitive(actual_type) {
378 return self.encode(buf, actual_type);
379 }
380 }
381 match t.as_ref() {
382 TypeInner::Null => sleb128_encode(buf, Opcode::Null as i64),
383 TypeInner::Bool => sleb128_encode(buf, Opcode::Bool as i64),
384 TypeInner::Nat => sleb128_encode(buf, Opcode::Nat as i64),
385 TypeInner::Int => sleb128_encode(buf, Opcode::Int as i64),
386 TypeInner::Nat8 => sleb128_encode(buf, Opcode::Nat8 as i64),
387 TypeInner::Nat16 => sleb128_encode(buf, Opcode::Nat16 as i64),
388 TypeInner::Nat32 => sleb128_encode(buf, Opcode::Nat32 as i64),
389 TypeInner::Nat64 => sleb128_encode(buf, Opcode::Nat64 as i64),
390 TypeInner::Int8 => sleb128_encode(buf, Opcode::Int8 as i64),
391 TypeInner::Int16 => sleb128_encode(buf, Opcode::Int16 as i64),
392 TypeInner::Int32 => sleb128_encode(buf, Opcode::Int32 as i64),
393 TypeInner::Int64 => sleb128_encode(buf, Opcode::Int64 as i64),
394 TypeInner::Float32 => sleb128_encode(buf, Opcode::Float32 as i64),
395 TypeInner::Float64 => sleb128_encode(buf, Opcode::Float64 as i64),
396 TypeInner::Text => sleb128_encode(buf, Opcode::Text as i64),
397 TypeInner::Reserved => sleb128_encode(buf, Opcode::Reserved as i64),
398 TypeInner::Empty => sleb128_encode(buf, Opcode::Empty as i64),
399 TypeInner::Principal => sleb128_encode(buf, Opcode::Principal as i64),
400 TypeInner::Knot(ref id) => {
401 let ty = types::internal::find_type(id)
402 .ok_or_else(|| Error::msg("knot TypeId not found"))?;
403 let idx = self
404 .type_map
405 .get(&ty)
406 .ok_or_else(|| Error::msg(format!("knot type {ty} not found")))?;
407 sleb128_encode(buf, i64::from(*idx))
408 }
409 TypeInner::Var(_) => {
410 let idx = self
411 .type_map
412 .get(t)
413 .ok_or_else(|| Error::msg(format!("var type {t} not found")))?;
414 sleb128_encode(buf, i64::from(*idx))
415 }
416 TypeInner::Future => unreachable!(),
417 _ => {
418 let idx = self
419 .type_map
420 .get(t)
421 .ok_or_else(|| Error::msg(format!("type {t} not found")))?;
422 sleb128_encode(buf, i64::from(*idx))
423 }
424 }?;
425 Ok(())
426 }
427 #[doc(hidden)]
428 pub fn serialize(&mut self) -> Result<()> {
429 leb128_encode(&mut self.result, self.type_table.len() as u64)?;
430 self.result.append(&mut self.type_table.concat());
431
432 leb128_encode(&mut self.result, self.args.len() as u64)?;
433 let mut ty_encode = Vec::new();
434 for t in &self.args {
435 self.encode(&mut ty_encode, t)?;
436 }
437 self.result.append(&mut ty_encode);
438 Ok(())
439 }
440}