• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 use crate::builder::Builder;
16 use crate::private::Sealed;
17 use crate::{Blob, Buffer, IndirectFloat, IndirectInt, IndirectUInt};
18 
19 impl<B: Buffer> Sealed for Blob<B> {}
20 impl Sealed for () {}
21 
22 // TODO: String interning
23 // TODO: Pushable for Map types?
24 
25 /// Types that implement the Pushable trait can be written into a Flexbuffer.
26 ///
27 /// All Rust's standard numbers, `u8, u16, u32, u64, i8, i16, i32, i64, f32, f64`,
28 /// can all be pushed. They are  `FlexBufferType::{UInt, Int, Float}`.
29 /// Flexbuffers chooses the smallest width that can represent the given number.
30 /// Strings can pe pushed, they become `FlexBufferType::String` and are stored
31 /// with both a length and null terminator.
32 ///
33 /// * For convenience and speed push typed vectors using rust arrays and slices.
34 /// Doing so will immediately serialize the data, skipping the `Builder`'s
35 /// internal cache.
36 ///
37 /// * Pushable cannot not be implemented by any downstream crates.
38 pub trait Pushable: Sealed + Sized {
push_to_builder(self, _: &mut Builder)39     fn push_to_builder(self, _: &mut Builder) {}
40 }
41 
42 impl Pushable for () {
push_to_builder(self, builder: &mut Builder)43     fn push_to_builder(self, builder: &mut Builder) {
44         builder.push_null();
45     }
46 }
47 
48 impl<B: Buffer> Pushable for Blob<B> {
push_to_builder(self, builder: &mut Builder)49     fn push_to_builder(self, builder: &mut Builder) {
50         builder.push_blob(&self.0);
51     }
52 }
53 
54 macro_rules! forward_to_builder {
55     ($T: ty, $method: ident) => {
56         impl Sealed for $T {}
57         impl Pushable for $T {
58             fn push_to_builder(self, builder: &mut Builder) {
59                 builder.$method(self);
60             }
61         }
62     };
63     ($T: ty, $method: ident, $asT: ty) => {
64         impl Sealed for $T {}
65         impl Pushable for $T {
66             fn push_to_builder(self, builder: &mut Builder) {
67                 builder.$method(self as $asT);
68             }
69         }
70     };
71 }
72 forward_to_builder!(&str, push_str);
73 forward_to_builder!(bool, push_bool);
74 forward_to_builder!(u8, push_uint);
75 forward_to_builder!(u16, push_uint);
76 forward_to_builder!(u32, push_uint);
77 forward_to_builder!(u64, push_uint);
78 forward_to_builder!(i8, push_int);
79 forward_to_builder!(i16, push_int);
80 forward_to_builder!(i32, push_int);
81 forward_to_builder!(i64, push_int);
82 forward_to_builder!(f32, push_float);
83 forward_to_builder!(f64, push_float);
84 forward_to_builder!(&[u8], push_uints);
85 forward_to_builder!(&[u16], push_uints);
86 forward_to_builder!(&[u32], push_uints);
87 forward_to_builder!(&[u64], push_uints);
88 forward_to_builder!(&[i8], push_ints);
89 forward_to_builder!(&[i16], push_ints);
90 forward_to_builder!(&[i32], push_ints);
91 forward_to_builder!(&[i64], push_ints);
92 forward_to_builder!(&[f32], push_floats);
93 forward_to_builder!(&[f64], push_floats);
94 forward_to_builder!(&[bool], push_bools);
95 forward_to_builder!(&Vec<u8>, push_uints);
96 forward_to_builder!(&Vec<u16>, push_uints);
97 forward_to_builder!(&Vec<u32>, push_uints);
98 forward_to_builder!(&Vec<u64>, push_uints);
99 forward_to_builder!(&Vec<i8>, push_ints);
100 forward_to_builder!(&Vec<i16>, push_ints);
101 forward_to_builder!(&Vec<i32>, push_ints);
102 forward_to_builder!(&Vec<i64>, push_ints);
103 forward_to_builder!(&Vec<f32>, push_floats);
104 forward_to_builder!(&Vec<f64>, push_floats);
105 forward_to_builder!(&Vec<bool>, push_bools);
106 
107 macro_rules! impl_indirects {
108     ($Indirect: ident, $method: ident) => {
109         impl Sealed for $Indirect {}
110         impl Pushable for $Indirect {
111             fn push_to_builder(self, builder: &mut Builder) {
112                 builder.$method(self.0);
113             }
114         }
115     };
116 }
117 impl_indirects!(IndirectInt, push_indirect_int);
118 impl_indirects!(IndirectUInt, push_indirect_uint);
119 impl_indirects!(IndirectFloat, push_indirect_float);
120 
121 macro_rules! impl_arrays {
122     ($num: expr) => {
123         forward_to_builder!(&[u8; $num], push_uints, &[u8]);
124         forward_to_builder!(&[u16; $num], push_uints, &[u16]);
125         forward_to_builder!(&[u32; $num], push_uints, &[u32]);
126         forward_to_builder!(&[u64; $num], push_uints, &[u64]);
127         forward_to_builder!(&[i8; $num], push_ints, &[i8]);
128         forward_to_builder!(&[i16; $num], push_ints, &[i16]);
129         forward_to_builder!(&[i32; $num], push_ints, &[i32]);
130         forward_to_builder!(&[i64; $num], push_ints, &[i64]);
131         forward_to_builder!(&[f32; $num], push_floats, &[f32]);
132         forward_to_builder!(&[f64; $num], push_floats, &[f64]);
133         forward_to_builder!(&[bool; $num], push_bools, &[bool]);
134     };
135 }
136 impl_arrays!(0);
137 impl_arrays!(1);
138 impl_arrays!(2);
139 impl_arrays!(3);
140 impl_arrays!(4);
141 impl_arrays!(5);
142 impl_arrays!(6);
143 // impl_arrays!(7);
144 // impl_arrays!(8);
145 // impl_arrays!(9);
146 // impl_arrays!(10);
147 // impl_arrays!(11);
148 // impl_arrays!(12);
149 // impl_arrays!(13);
150 // impl_arrays!(14);
151 // impl_arrays!(15);
152 // impl_arrays!(16);
153 // impl_arrays!(17);
154 // impl_arrays!(18);
155 // impl_arrays!(19);
156 // impl_arrays!(20);
157 // impl_arrays!(21);
158 // impl_arrays!(22);
159 // impl_arrays!(23);
160 // impl_arrays!(24);
161 // impl_arrays!(25);
162 // impl_arrays!(26);
163 // impl_arrays!(27);
164 // impl_arrays!(28);
165 // impl_arrays!(29);
166 // impl_arrays!(30);
167 // impl_arrays!(31);
168 // impl_arrays!(32);
169