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