gluon_vm/api/
ser.rs

1//! Rust -> Gluon value conversion via the `serde::Serialize` trait
2//!
3//! _This module requires Gluon to be built with the `serde` feature._
4
5use std::{
6    fmt,
7    ops::{Deref, DerefMut},
8};
9
10use crate::{
11    api::{Pushable, VmType},
12    base::types::ArcType,
13    interner::InternedStr,
14    serde::ser::{self, Serialize},
15    thread::{ActiveThread, Thread},
16    types::{VmIndex, VmTag},
17    value::{Def, RecordDef, ValueRepr},
18    Error, Result, Variants,
19};
20
21/**
22`Pushable` wrapper which pushes `T` by serializing it.
23
24## Struct
25
26```
27use serde::Serialize;
28
29use gluon_vm::{field_decl, record_type};
30
31use gluon::{
32    Thread, ThreadExt, new_vm_async,
33    base::types::ArcType,
34    vm::api::{ser::Ser, FunctionRef, VmType},
35};
36
37# #[tokio::main]
38# async fn main() {
39
40#[derive(Serialize)]
41struct Vec2 {
42    x: i32,
43    y: i32,
44}
45
46impl VmType for Vec2 {
47    type Type = Self;
48
49    fn make_type(thread: &Thread) -> ArcType {
50        field_decl!{ x, y }
51        type T = record_type! {
52            x => i32,
53            y => i32
54        };
55        T::make_type(thread)
56    }
57}
58
59# if ::std::env::var("GLUON_PATH").is_err() {
60#     ::std::env::set_var("GLUON_PATH", "..");
61# }
62
63let thread = new_vm_async().await;
64
65let (mut f, _): (FunctionRef<fn (Ser<Vec2>) -> i32>, _) = thread
66    .run_expr_async("", r#"let f v: _ -> Int = v.x + v.y in f"#)
67    .await
68    .unwrap_or_else(|err| panic!("{}", err));
69let vec = Vec2 {
70    x: 3,
71    y: 10
72};
73let result = f.call_async(Ser(vec)).await.unwrap_or_else(|err| panic!("{}", err));
74assert_eq!(result, 13);
75# }
76
77```
78
79## Enum
80
81```
82#[macro_use]
83extern crate serde_derive;
84
85#[macro_use]
86extern crate gluon_vm;
87
88use gluon::{Thread, ThreadExt, new_vm};
89use gluon::base::types::ArcType;
90use gluon::vm::api::{FunctionRef, VmType};
91use gluon::vm::api::ser::Ser;
92# fn main() {
93
94
95#[derive(Serialize)]
96enum Enum {
97    A(i32),
98    B(String, i32),
99    C { foo: f64, bar: i32 },
100}
101
102impl VmType for Enum {
103    type Type = Self;
104
105    fn make_type(thread: &Thread) -> ArcType {
106        // Use the enum type declared in gluon
107        thread.find_type_info("test.Enum").unwrap().into_type()
108    }
109}
110
111# if ::std::env::var("GLUON_PATH").is_err() {
112#     ::std::env::set_var("GLUON_PATH", "..");
113# }
114
115let thread = new_vm();
116# thread.get_database_mut().implicit_prelude(false);
117
118let expr = r#"
119type Enum = | A Int | B String Int | C { foo : Float, bar : Int }
120
121let extract_bar r : { bar : Int | r } -> Int = r.bar
122
123let f e =
124    match e with
125    | A a -> a
126    | B b c -> c
127    | C c -> extract_bar c
128
129{ Enum, f }
130"#;
131thread
132    .load_script("test", expr)
133    .unwrap_or_else(|err| panic!("{}", err));
134
135let mut f: FunctionRef<fn (Ser<Enum>) -> i32> = thread
136    .get_global("test.f")
137    .unwrap_or_else(|err| panic!("{}", err));
138
139let result1 = f.call(Ser(Enum::B("".to_string(), 4)))
140    .unwrap_or_else(|err| panic!("{}", err));
141assert_eq!(result1, 4);
142
143let result2 = f.call(Ser(Enum::C { foo: 3.14, bar: 10 }))
144    .unwrap_or_else(|err| panic!("{}", err));
145assert_eq!(result2, 10);
146
147# }
148```
149*/
150pub struct Ser<T>(pub T);
151
152impl<T> VmType for Ser<T>
153where
154    T: VmType,
155{
156    type Type = T::Type;
157
158    fn make_type(thread: &Thread) -> ArcType {
159        T::make_type(thread)
160    }
161}
162
163impl<'vm, T> Pushable<'vm> for Ser<T>
164where
165    T: Serialize,
166{
167    fn vm_push(self, context: &mut ActiveThread<'vm>) -> Result<()> {
168        let mut serializer = Serializer::new(context);
169        self.0.serialize(&mut serializer)
170    }
171}
172
173impl ser::Error for Error {
174    fn custom<T>(msg: T) -> Self
175    where
176        T: fmt::Display,
177    {
178        Error::Message(format!("{}", msg))
179    }
180}
181
182pub struct Serializer<'a, 't: 'a> {
183    thread: &'t Thread,
184    context: &'a mut ActiveThread<'t>,
185}
186
187impl<'a, 't> Serializer<'a, 't> {
188    pub fn new(context: &'a mut ActiveThread<'t>) -> Self {
189        Serializer {
190            thread: context.thread(),
191            context,
192        }
193    }
194
195    fn to_value<T>(&mut self, value: T) -> Result<()>
196    where
197        T: Pushable<'t>,
198    {
199        value.vm_push(self.context)
200    }
201
202    fn alloc(&mut self, tag: VmTag, values: VmIndex) -> Result<()> {
203        let mut context = self.context.context();
204        let value = context.gc.alloc(Def {
205            tag: tag,
206            elems: &context.stack[context.stack.len() - values..],
207        })?;
208        context.stack.pop_many(values);
209        context.stack.push(Variants::from(value));
210        Ok(())
211    }
212
213    fn alloc_record(&mut self, fields: &[InternedStr], values: VmIndex) -> Result<()> {
214        let mut context = self.context.context();
215        let value = context.gc.alloc(RecordDef {
216            elems: &context.stack[context.stack.len() - values..],
217            fields,
218        })?;
219        context.stack.pop_many(values);
220        context.stack.push(Variants::from(value));
221        Ok(())
222    }
223}
224
225#[doc(hidden)]
226pub struct RecordSerializer<'s, 'a: 's, 'vm: 'a> {
227    serializer: &'s mut Serializer<'a, 'vm>,
228    variant_index: VmTag,
229    values: VmIndex,
230    fields: Vec<InternedStr>,
231}
232
233impl<'s, 'a, 'vm> Deref for RecordSerializer<'s, 'a, 'vm> {
234    type Target = Serializer<'a, 'vm>;
235    fn deref(&self) -> &Self::Target {
236        self.serializer
237    }
238}
239
240impl<'s, 'a, 'vm> DerefMut for RecordSerializer<'s, 'a, 'vm> {
241    fn deref_mut(&mut self) -> &mut Self::Target {
242        self.serializer
243    }
244}
245
246impl<'s, 'a, 'vm> RecordSerializer<'s, 'a, 'vm> {
247    fn new(serializer: &'s mut Serializer<'a, 'vm>, variant_index: u32) -> Self {
248        RecordSerializer {
249            serializer: serializer,
250            variant_index: variant_index,
251            values: 0,
252            fields: Vec::new(),
253        }
254    }
255}
256
257impl<'s, 'a, 'vm> ser::Serializer for &'s mut Serializer<'a, 'vm> {
258    type Ok = ();
259
260    // The error type when some error occurs during serialization.
261    type Error = Error;
262
263    // Associated types for keeping track of additional state while serializing
264    // compound data structures like sequences and maps. In this case no
265    // additional state is required beyond what is already stored in the
266    // Serializer struct.
267    type SerializeSeq = RecordSerializer<'s, 'a, 'vm>;
268    type SerializeTuple = RecordSerializer<'s, 'a, 'vm>;
269    type SerializeTupleStruct = RecordSerializer<'s, 'a, 'vm>;
270    type SerializeTupleVariant = RecordSerializer<'s, 'a, 'vm>;
271    type SerializeMap = RecordSerializer<'s, 'a, 'vm>;
272    type SerializeStruct = RecordSerializer<'s, 'a, 'vm>;
273    type SerializeStructVariant = RecordSerializer<'s, 'a, 'vm>;
274
275    // Here we go with the simple methods. The following 12 methods receive one
276    // of the primitive types of the data model and map it to JSON by appending
277    // into the output string.
278    fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
279        self.to_value(v)
280    }
281
282    // JSON does not distinguish between different sizes of integers, so all
283    // signed integers will be serialized the same and all unsigned integers
284    // will be serialized the same. Other formats, especially compact binary
285    // formats, may need independent logic for the different sizes.
286    fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
287        self.serialize_i64(v as i64)
288    }
289
290    fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
291        self.serialize_i64(v as i64)
292    }
293
294    fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
295        self.serialize_i64(v as i64)
296    }
297
298    // Not particularly efficient but this is example code anyway. A more
299    // performant approach would be to use the `itoa` crate.
300    fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
301        self.to_value(v as isize)
302    }
303
304    fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
305        self.serialize_u64(v as u64)
306    }
307
308    fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
309        self.serialize_u64(v as u64)
310    }
311
312    fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
313        self.serialize_u64(v as u64)
314    }
315
316    fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
317        self.to_value(v as isize)
318    }
319
320    fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
321        self.serialize_f64(v as f64)
322    }
323
324    fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
325        self.to_value(v)
326    }
327
328    fn serialize_char(self, v: char) -> Result<Self::Ok> {
329        self.serialize_str(&v.to_string())
330    }
331
332    fn serialize_str(self, v: &str) -> Result<Self::Ok> {
333        self.to_value(v)
334    }
335
336    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> {
337        self.to_value(v)
338    }
339
340    // An absent optional is represented as the JSON `null`.
341    fn serialize_none(self) -> Result<Self::Ok> {
342        self.serialize_unit()
343    }
344
345    // A present optional is represented as just the contained value. Note that
346    // this is a lossy representation. For example the values `Some(())` and
347    // `None` both serialize as just `null`. Unfortunately this is typically
348    // what people expect when working with JSON. Other formats are encouraged
349    // to behave more intelligently if possible.
350    fn serialize_some<T>(self, value: &T) -> Result<Self::Ok>
351    where
352        T: ?Sized + Serialize,
353    {
354        value.serialize(self)
355    }
356
357    fn serialize_unit(self) -> Result<Self::Ok> {
358        self.context.push(ValueRepr::Tag(0));
359        Ok(())
360    }
361
362    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
363        self.serialize_unit()
364    }
365
366    fn serialize_unit_variant(
367        self,
368        _name: &'static str,
369        variant_index: u32,
370        _variant: &'static str,
371    ) -> Result<Self::Ok> {
372        self.context.push(ValueRepr::Tag(variant_index));
373        Ok(())
374    }
375
376    // As is done here, serializers are encouraged to treat newtype structs as
377    // insignificant wrappers around the data they contain.
378    fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<Self::Ok>
379    where
380        T: ?Sized + Serialize,
381    {
382        value.serialize(self)
383    }
384
385    // Note that newtype variant (and all of the other variant serialization
386    // methods) refer exclusively to the "externally tagged" enum
387    // representation.
388    //
389    // Serialize this to JSON in externally tagged form as `{ NAME: VALUE }`.
390    fn serialize_newtype_variant<T>(
391        self,
392        _name: &'static str,
393        variant_index: u32,
394        _variant: &'static str,
395        value: &T,
396    ) -> Result<Self::Ok>
397    where
398        T: ?Sized + Serialize,
399    {
400        value.serialize(&mut *self)?;
401        self.alloc(variant_index, 1)
402    }
403
404    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
405        Ok(RecordSerializer::new(self, 0))
406    }
407
408    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
409        self.serialize_seq(Some(len))
410    }
411
412    fn serialize_tuple_struct(
413        self,
414        _name: &'static str,
415        len: usize,
416    ) -> Result<Self::SerializeTupleStruct> {
417        self.serialize_seq(Some(len))
418    }
419
420    fn serialize_tuple_variant(
421        self,
422        _name: &'static str,
423        variant_index: u32,
424        _variant: &'static str,
425        _len: usize,
426    ) -> Result<Self::SerializeTupleVariant> {
427        Ok(RecordSerializer::new(self, variant_index))
428    }
429
430    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
431        Ok(RecordSerializer::new(self, 0))
432    }
433
434    fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
435        self.serialize_map(Some(len))
436    }
437
438    fn serialize_struct_variant(
439        self,
440        _name: &'static str,
441        variant_index: u32,
442        _variant: &'static str,
443        _len: usize,
444    ) -> Result<Self::SerializeStructVariant> {
445        Ok(RecordSerializer::new(self, variant_index))
446    }
447}
448
449impl<'s, 'a, 'vm> ser::SerializeSeq for RecordSerializer<'s, 'a, 'vm> {
450    type Ok = ();
451    type Error = Error;
452
453    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
454    where
455        T: ?Sized + Serialize,
456    {
457        value.serialize(&mut **self)?;
458        self.values += 1;
459        Ok(())
460    }
461
462    fn end(self) -> Result<Self::Ok> {
463        self.serializer.alloc(self.variant_index, self.values)
464    }
465}
466
467impl<'s, 'a, 'vm> ser::SerializeTuple for RecordSerializer<'s, 'a, 'vm> {
468    type Ok = ();
469    type Error = Error;
470
471    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
472    where
473        T: ?Sized + Serialize,
474    {
475        value.serialize(&mut **self)?;
476        self.values += 1;
477        Ok(())
478    }
479
480    fn end(self) -> Result<Self::Ok> {
481        self.serializer.alloc(self.variant_index, self.values)
482    }
483}
484
485impl<'s, 'a, 'vm> ser::SerializeTupleStruct for RecordSerializer<'s, 'a, 'vm> {
486    type Ok = ();
487    type Error = Error;
488
489    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
490    where
491        T: ?Sized + Serialize,
492    {
493        value.serialize(&mut **self)?;
494        self.values += 1;
495        Ok(())
496    }
497
498    fn end(self) -> Result<Self::Ok> {
499        self.serializer.alloc(self.variant_index, self.values)
500    }
501}
502
503impl<'s, 'a, 'vm> ser::SerializeTupleVariant for RecordSerializer<'s, 'a, 'vm> {
504    type Ok = ();
505    type Error = Error;
506
507    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
508    where
509        T: ?Sized + Serialize,
510    {
511        value.serialize(&mut **self)?;
512        self.values += 1;
513        Ok(())
514    }
515
516    fn end(self) -> Result<Self::Ok> {
517        self.serializer.alloc(self.variant_index, self.values)
518    }
519}
520
521impl<'s, 'a, 'vm> ser::SerializeMap for RecordSerializer<'s, 'a, 'vm> {
522    type Ok = ();
523    type Error = Error;
524
525    fn serialize_key<T>(&mut self, _key: &T) -> Result<()>
526    where
527        T: ?Sized + Serialize,
528    {
529        Ok(())
530    }
531
532    fn serialize_value<T>(&mut self, value: &T) -> Result<()>
533    where
534        T: ?Sized + Serialize,
535    {
536        value.serialize(&mut **self)?;
537        self.values += 1;
538        Ok(())
539    }
540
541    fn end(self) -> Result<Self::Ok> {
542        self.serializer.alloc(self.variant_index, self.values)
543    }
544}
545
546impl<'s, 'a, 'vm> ser::SerializeStruct for RecordSerializer<'s, 'a, 'vm> {
547    type Ok = ();
548    type Error = Error;
549
550    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
551    where
552        T: ?Sized + Serialize,
553    {
554        let field = self.thread.global_env().intern(key)?;
555        self.fields.push(field);
556        value.serialize(&mut **self)?;
557        self.values += 1;
558        Ok(())
559    }
560
561    fn end(self) -> Result<Self::Ok> {
562        self.serializer.alloc_record(&self.fields, self.values)
563    }
564}
565
566// Similar to `SerializeTupleVariant`, here the `end` method is responsible for
567// closing both of the curly braces opened by `serialize_struct_variant`.
568impl<'s, 'a, 'vm> ser::SerializeStructVariant for RecordSerializer<'s, 'a, 'vm> {
569    type Ok = ();
570    type Error = Error;
571
572    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
573    where
574        T: ?Sized + Serialize,
575    {
576        let field = self.thread.global_env().intern(key)?;
577        self.fields.push(field);
578        value.serialize(&mut **self)?;
579        self.values += 1;
580        Ok(())
581    }
582
583    fn end(self) -> Result<Self::Ok> {
584        self.serializer.alloc_record(&self.fields, self.values)?;
585        self.serializer.alloc(self.variant_index, 1)
586    }
587}
588
589#[cfg(test)]
590mod tests {
591    use super::*;
592    use crate::{thread::RootedThread, value::Value};
593
594    #[test]
595    fn bool() {
596        let thread = RootedThread::new();
597        assert_eq!(
598            true.marshal::<&Thread>(&thread).unwrap().get_value(),
599            &Value::tag(1)
600        );
601    }
602}