Apply Ocamlvalue derive to oxidized aast related types
[hiphop-php.git] / hphp / hack / src / utils / ocamlpool_rust / ocamlvalue.rs
blob971e70571619f04e5b2af5cf40460ac5ef1db721
1 // Copyright (c) 2019, Facebook, Inc.
2 // All rights reserved.
3 //
4 // This source code is licensed under the MIT license found in the
5 // LICENSE file in the "hack" directory of this source tree.
7 extern crate ocaml;
9 use crate::utils::*;
11 use ocaml::core::mlvalues::{empty_list, Value, UNIT};
12 use std::borrow::Cow;
14 const DOUBLE_TAG: u8 = 253;
16 pub trait Ocamlvalue {
17     fn ocamlvalue(&self) -> Value;
20 impl<T: Ocamlvalue> Ocamlvalue for std::boxed::Box<T> {
21     fn ocamlvalue(&self) -> Value {
22         self.as_ref().ocamlvalue()
23     }
26 impl<T: Ocamlvalue> Ocamlvalue for std::vec::Vec<T> {
27     fn ocamlvalue(&self) -> Value {
28         let mut res = empty_list();
30         for v in self.iter().rev() {
31             res = caml_tuple(&[v.ocamlvalue(), res])
32         }
33         res
34     }
37 impl<T: Ocamlvalue> Ocamlvalue for Option<T> {
38     fn ocamlvalue(&self) -> Value {
39         match self {
40             None => usize_to_ocaml(0),
41             Some(x) => caml_tuple(&[x.ocamlvalue()]),
42         }
43     }
46 impl Ocamlvalue for String {
47     fn ocamlvalue(&self) -> Value {
48         str_to_ocaml(self.as_bytes())
49     }
52 impl Ocamlvalue for Cow<'static, str> {
53     fn ocamlvalue(&self) -> Value {
54         str_to_ocaml(self.as_bytes())
55     }
58 impl Ocamlvalue for bool {
59     fn ocamlvalue(&self) -> Value {
60         usize_to_ocaml(*self as usize)
61     }
64 impl Ocamlvalue for () {
65     fn ocamlvalue(&self) -> Value {
66         UNIT
67     }
70 impl<T1: Ocamlvalue, T2: Ocamlvalue> Ocamlvalue for (T1, T2) {
71     fn ocamlvalue(&self) -> Value {
72         caml_tuple(&[self.0.ocamlvalue(), self.1.ocamlvalue()])
73     }
76 impl<T1: Ocamlvalue, T2: Ocamlvalue, T3: Ocamlvalue> Ocamlvalue for (T1, T2, T3) {
77     fn ocamlvalue(&self) -> Value {
78         caml_tuple(&[
79             self.0.ocamlvalue(),
80             self.1.ocamlvalue(),
81             self.2.ocamlvalue(),
82         ])
83     }
86 impl<T1: Ocamlvalue, T2: Ocamlvalue, T3: Ocamlvalue, T4: Ocamlvalue> Ocamlvalue
87     for (T1, T2, T3, T4)
89     fn ocamlvalue(&self) -> Value {
90         caml_tuple(&[
91             self.0.ocamlvalue(),
92             self.1.ocamlvalue(),
93             self.2.ocamlvalue(),
94             self.3.ocamlvalue(),
95         ])
96     }
99 impl Ocamlvalue for i8 {
100     fn ocamlvalue(&self) -> Value {
101         usize_to_ocaml(*self as usize)
102     }
105 impl Ocamlvalue for usize {
106     fn ocamlvalue(&self) -> Value {
107         usize_to_ocaml(*self as usize)
108     }
111 impl Ocamlvalue for isize {
112     fn ocamlvalue(&self) -> Value {
113         ((*self << 1) + 1) as usize
114     }
117 impl Ocamlvalue for u64 {
118     fn ocamlvalue(&self) -> Value {
119         ((*self << 1) + 1) as usize
120     }
123 impl Ocamlvalue for f64 {
124     fn ocamlvalue(&self) -> Value {
125         caml_block(DOUBLE_TAG, &[(*self).to_bits() as usize])
126     }