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 super::Error; 16*890232f2SAndroid Build Coastguard Worker use crate::{FlexBufferType, Reader, ReaderIterator}; 17*890232f2SAndroid Build Coastguard Worker use serde::de::{ 18*890232f2SAndroid Build Coastguard Worker DeserializeSeed, Deserializer, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, 19*890232f2SAndroid Build Coastguard Worker VariantAccess, Visitor, 20*890232f2SAndroid Build Coastguard Worker }; 21*890232f2SAndroid Build Coastguard Worker 22*890232f2SAndroid Build Coastguard Worker /// Errors that may happen when deserializing a flexbuffer with serde. 23*890232f2SAndroid Build Coastguard Worker #[derive(Debug, Clone, PartialEq, Eq)] 24*890232f2SAndroid Build Coastguard Worker pub enum DeserializationError { 25*890232f2SAndroid Build Coastguard Worker Reader(Error), 26*890232f2SAndroid Build Coastguard Worker Serde(String), 27*890232f2SAndroid Build Coastguard Worker } 28*890232f2SAndroid Build Coastguard Worker 29*890232f2SAndroid Build Coastguard Worker impl std::error::Error for DeserializationError {} 30*890232f2SAndroid Build Coastguard Worker impl std::fmt::Display for DeserializationError { fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error>31*890232f2SAndroid Build Coastguard Worker fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { 32*890232f2SAndroid Build Coastguard Worker match self { 33*890232f2SAndroid Build Coastguard Worker Self::Reader(r) => write!(f, "Flexbuffer Read Error: {:?}", r), 34*890232f2SAndroid Build Coastguard Worker Self::Serde(s) => write!(f, "Serde Error: {}", s), 35*890232f2SAndroid Build Coastguard Worker } 36*890232f2SAndroid Build Coastguard Worker } 37*890232f2SAndroid Build Coastguard Worker } 38*890232f2SAndroid Build Coastguard Worker 39*890232f2SAndroid Build Coastguard Worker impl serde::de::Error for DeserializationError { custom<T>(msg: T) -> Self where T: std::fmt::Display,40*890232f2SAndroid Build Coastguard Worker fn custom<T>(msg: T) -> Self 41*890232f2SAndroid Build Coastguard Worker where 42*890232f2SAndroid Build Coastguard Worker T: std::fmt::Display, 43*890232f2SAndroid Build Coastguard Worker { 44*890232f2SAndroid Build Coastguard Worker Self::Serde(format!("{}", msg)) 45*890232f2SAndroid Build Coastguard Worker } 46*890232f2SAndroid Build Coastguard Worker } 47*890232f2SAndroid Build Coastguard Worker 48*890232f2SAndroid Build Coastguard Worker impl std::convert::From<super::Error> for DeserializationError { from(e: super::Error) -> Self49*890232f2SAndroid Build Coastguard Worker fn from(e: super::Error) -> Self { 50*890232f2SAndroid Build Coastguard Worker Self::Reader(e) 51*890232f2SAndroid Build Coastguard Worker } 52*890232f2SAndroid Build Coastguard Worker } 53*890232f2SAndroid Build Coastguard Worker 54*890232f2SAndroid Build Coastguard Worker impl<'de> SeqAccess<'de> for ReaderIterator<&'de [u8]> { 55*890232f2SAndroid Build Coastguard Worker type Error = DeserializationError; 56*890232f2SAndroid Build Coastguard Worker next_element_seed<T>( &mut self, seed: T, ) -> Result<Option<<T as DeserializeSeed<'de>>::Value>, Self::Error> where T: DeserializeSeed<'de>,57*890232f2SAndroid Build Coastguard Worker fn next_element_seed<T>( 58*890232f2SAndroid Build Coastguard Worker &mut self, 59*890232f2SAndroid Build Coastguard Worker seed: T, 60*890232f2SAndroid Build Coastguard Worker ) -> Result<Option<<T as DeserializeSeed<'de>>::Value>, Self::Error> 61*890232f2SAndroid Build Coastguard Worker where 62*890232f2SAndroid Build Coastguard Worker T: DeserializeSeed<'de>, 63*890232f2SAndroid Build Coastguard Worker { 64*890232f2SAndroid Build Coastguard Worker if let Some(elem) = self.next() { 65*890232f2SAndroid Build Coastguard Worker seed.deserialize(elem).map(Some) 66*890232f2SAndroid Build Coastguard Worker } else { 67*890232f2SAndroid Build Coastguard Worker Ok(None) 68*890232f2SAndroid Build Coastguard Worker } 69*890232f2SAndroid Build Coastguard Worker } 70*890232f2SAndroid Build Coastguard Worker size_hint(&self) -> Option<usize>71*890232f2SAndroid Build Coastguard Worker fn size_hint(&self) -> Option<usize> { 72*890232f2SAndroid Build Coastguard Worker Some(self.len()) 73*890232f2SAndroid Build Coastguard Worker } 74*890232f2SAndroid Build Coastguard Worker } 75*890232f2SAndroid Build Coastguard Worker 76*890232f2SAndroid Build Coastguard Worker struct EnumReader<'de> { 77*890232f2SAndroid Build Coastguard Worker variant: &'de str, 78*890232f2SAndroid Build Coastguard Worker value: Option<Reader<&'de [u8]>>, 79*890232f2SAndroid Build Coastguard Worker } 80*890232f2SAndroid Build Coastguard Worker 81*890232f2SAndroid Build Coastguard Worker impl<'de> EnumAccess<'de> for EnumReader<'de> { 82*890232f2SAndroid Build Coastguard Worker type Error = DeserializationError; 83*890232f2SAndroid Build Coastguard Worker type Variant = Reader<&'de [u8]>; 84*890232f2SAndroid Build Coastguard Worker variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> where V: DeserializeSeed<'de>,85*890232f2SAndroid Build Coastguard Worker fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> 86*890232f2SAndroid Build Coastguard Worker where 87*890232f2SAndroid Build Coastguard Worker V: DeserializeSeed<'de>, 88*890232f2SAndroid Build Coastguard Worker { 89*890232f2SAndroid Build Coastguard Worker seed.deserialize(self.variant.into_deserializer()) 90*890232f2SAndroid Build Coastguard Worker .map(|v| (v, self.value.unwrap_or_default())) 91*890232f2SAndroid Build Coastguard Worker } 92*890232f2SAndroid Build Coastguard Worker } 93*890232f2SAndroid Build Coastguard Worker 94*890232f2SAndroid Build Coastguard Worker struct MapAccessor<'de> { 95*890232f2SAndroid Build Coastguard Worker keys: ReaderIterator<&'de [u8]>, 96*890232f2SAndroid Build Coastguard Worker vals: ReaderIterator<&'de [u8]>, 97*890232f2SAndroid Build Coastguard Worker } 98*890232f2SAndroid Build Coastguard Worker 99*890232f2SAndroid Build Coastguard Worker impl<'de> MapAccess<'de> for MapAccessor<'de> { 100*890232f2SAndroid Build Coastguard Worker type Error = DeserializationError; 101*890232f2SAndroid Build Coastguard Worker next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error> where K: DeserializeSeed<'de>,102*890232f2SAndroid Build Coastguard Worker fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error> 103*890232f2SAndroid Build Coastguard Worker where 104*890232f2SAndroid Build Coastguard Worker K: DeserializeSeed<'de>, 105*890232f2SAndroid Build Coastguard Worker { 106*890232f2SAndroid Build Coastguard Worker if let Some(k) = self.keys.next() { 107*890232f2SAndroid Build Coastguard Worker seed.deserialize(k).map(Some) 108*890232f2SAndroid Build Coastguard Worker } else { 109*890232f2SAndroid Build Coastguard Worker Ok(None) 110*890232f2SAndroid Build Coastguard Worker } 111*890232f2SAndroid Build Coastguard Worker } 112*890232f2SAndroid Build Coastguard Worker next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error> where V: DeserializeSeed<'de>,113*890232f2SAndroid Build Coastguard Worker fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error> 114*890232f2SAndroid Build Coastguard Worker where 115*890232f2SAndroid Build Coastguard Worker V: DeserializeSeed<'de>, 116*890232f2SAndroid Build Coastguard Worker { 117*890232f2SAndroid Build Coastguard Worker let val = self.vals.next().ok_or(Error::IndexOutOfBounds)?; 118*890232f2SAndroid Build Coastguard Worker seed.deserialize(val) 119*890232f2SAndroid Build Coastguard Worker } 120*890232f2SAndroid Build Coastguard Worker } 121*890232f2SAndroid Build Coastguard Worker 122*890232f2SAndroid Build Coastguard Worker impl<'de> VariantAccess<'de> for Reader<&'de [u8]> { 123*890232f2SAndroid Build Coastguard Worker type Error = DeserializationError; 124*890232f2SAndroid Build Coastguard Worker unit_variant(self) -> Result<(), Self::Error>125*890232f2SAndroid Build Coastguard Worker fn unit_variant(self) -> Result<(), Self::Error> { 126*890232f2SAndroid Build Coastguard Worker Ok(()) 127*890232f2SAndroid Build Coastguard Worker } 128*890232f2SAndroid Build Coastguard Worker newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error> where T: DeserializeSeed<'de>,129*890232f2SAndroid Build Coastguard Worker fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error> 130*890232f2SAndroid Build Coastguard Worker where 131*890232f2SAndroid Build Coastguard Worker T: DeserializeSeed<'de>, 132*890232f2SAndroid Build Coastguard Worker { 133*890232f2SAndroid Build Coastguard Worker seed.deserialize(self) 134*890232f2SAndroid Build Coastguard Worker } 135*890232f2SAndroid Build Coastguard Worker 136*890232f2SAndroid Build Coastguard Worker // Tuple variants have an internally tagged representation. They are vectors where Index 0 is 137*890232f2SAndroid Build Coastguard Worker // the discriminant and index N is field N-1. tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,138*890232f2SAndroid Build Coastguard Worker fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error> 139*890232f2SAndroid Build Coastguard Worker where 140*890232f2SAndroid Build Coastguard Worker V: Visitor<'de>, 141*890232f2SAndroid Build Coastguard Worker { 142*890232f2SAndroid Build Coastguard Worker visitor.visit_seq(self.as_vector().iter()) 143*890232f2SAndroid Build Coastguard Worker } 144*890232f2SAndroid Build Coastguard Worker 145*890232f2SAndroid Build Coastguard Worker // Struct variants have an internally tagged representation. They are vectors where Index 0 is 146*890232f2SAndroid Build Coastguard Worker // the discriminant and index N is field N-1. struct_variant<V>( self, _fields: &'static [&'static str], visitor: V, ) -> Result<V::Value, Self::Error> where V: Visitor<'de>,147*890232f2SAndroid Build Coastguard Worker fn struct_variant<V>( 148*890232f2SAndroid Build Coastguard Worker self, 149*890232f2SAndroid Build Coastguard Worker _fields: &'static [&'static str], 150*890232f2SAndroid Build Coastguard Worker visitor: V, 151*890232f2SAndroid Build Coastguard Worker ) -> Result<V::Value, Self::Error> 152*890232f2SAndroid Build Coastguard Worker where 153*890232f2SAndroid Build Coastguard Worker V: Visitor<'de>, 154*890232f2SAndroid Build Coastguard Worker { 155*890232f2SAndroid Build Coastguard Worker let m = self.get_map()?; 156*890232f2SAndroid Build Coastguard Worker visitor.visit_map(MapAccessor { 157*890232f2SAndroid Build Coastguard Worker keys: m.keys_vector().iter(), 158*890232f2SAndroid Build Coastguard Worker vals: m.iter_values(), 159*890232f2SAndroid Build Coastguard Worker }) 160*890232f2SAndroid Build Coastguard Worker } 161*890232f2SAndroid Build Coastguard Worker } 162*890232f2SAndroid Build Coastguard Worker 163*890232f2SAndroid Build Coastguard Worker impl<'de> Deserializer<'de> for Reader<&'de [u8]> { 164*890232f2SAndroid Build Coastguard Worker type Error = DeserializationError; is_human_readable(&self) -> bool165*890232f2SAndroid Build Coastguard Worker fn is_human_readable(&self) -> bool { 166*890232f2SAndroid Build Coastguard Worker cfg!(deserialize_human_readable) 167*890232f2SAndroid Build Coastguard Worker } 168*890232f2SAndroid Build Coastguard Worker deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,169*890232f2SAndroid Build Coastguard Worker fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> 170*890232f2SAndroid Build Coastguard Worker where 171*890232f2SAndroid Build Coastguard Worker V: Visitor<'de>, 172*890232f2SAndroid Build Coastguard Worker { 173*890232f2SAndroid Build Coastguard Worker use crate::BitWidth::*; 174*890232f2SAndroid Build Coastguard Worker use crate::FlexBufferType::*; 175*890232f2SAndroid Build Coastguard Worker match (self.flexbuffer_type(), self.bitwidth()) { 176*890232f2SAndroid Build Coastguard Worker (Bool, _) => visitor.visit_bool(self.as_bool()), 177*890232f2SAndroid Build Coastguard Worker (UInt, W8) => visitor.visit_u8(self.as_u8()), 178*890232f2SAndroid Build Coastguard Worker (UInt, W16) => visitor.visit_u16(self.as_u16()), 179*890232f2SAndroid Build Coastguard Worker (UInt, W32) => visitor.visit_u32(self.as_u32()), 180*890232f2SAndroid Build Coastguard Worker (UInt, W64) => visitor.visit_u64(self.as_u64()), 181*890232f2SAndroid Build Coastguard Worker (Int, W8) => visitor.visit_i8(self.as_i8()), 182*890232f2SAndroid Build Coastguard Worker (Int, W16) => visitor.visit_i16(self.as_i16()), 183*890232f2SAndroid Build Coastguard Worker (Int, W32) => visitor.visit_i32(self.as_i32()), 184*890232f2SAndroid Build Coastguard Worker (Int, W64) => visitor.visit_i64(self.as_i64()), 185*890232f2SAndroid Build Coastguard Worker (Float, W32) => visitor.visit_f32(self.as_f32()), 186*890232f2SAndroid Build Coastguard Worker (Float, W64) => visitor.visit_f64(self.as_f64()), 187*890232f2SAndroid Build Coastguard Worker (Float, _) => Err(Error::InvalidPackedType.into()), // f8 and f16 are not supported. 188*890232f2SAndroid Build Coastguard Worker (Null, _) => visitor.visit_unit(), 189*890232f2SAndroid Build Coastguard Worker (String, _) | (Key, _) => visitor.visit_borrowed_str(self.as_str()), 190*890232f2SAndroid Build Coastguard Worker (Blob, _) => visitor.visit_borrowed_bytes(self.get_blob()?.0), 191*890232f2SAndroid Build Coastguard Worker (Map, _) => { 192*890232f2SAndroid Build Coastguard Worker let m = self.get_map()?; 193*890232f2SAndroid Build Coastguard Worker visitor.visit_map(MapAccessor { 194*890232f2SAndroid Build Coastguard Worker keys: m.keys_vector().iter(), 195*890232f2SAndroid Build Coastguard Worker vals: m.iter_values(), 196*890232f2SAndroid Build Coastguard Worker }) 197*890232f2SAndroid Build Coastguard Worker } 198*890232f2SAndroid Build Coastguard Worker (ty, _) if ty.is_vector() => visitor.visit_seq(self.as_vector().iter()), 199*890232f2SAndroid Build Coastguard Worker (ty, bw) => unreachable!("TODO deserialize_any {:?} {:?}.", ty, bw), 200*890232f2SAndroid Build Coastguard Worker } 201*890232f2SAndroid Build Coastguard Worker } 202*890232f2SAndroid Build Coastguard Worker 203*890232f2SAndroid Build Coastguard Worker serde::forward_to_deserialize_any! { 204*890232f2SAndroid Build Coastguard Worker bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 str unit unit_struct bytes 205*890232f2SAndroid Build Coastguard Worker ignored_any map identifier struct tuple tuple_struct seq string 206*890232f2SAndroid Build Coastguard Worker } 207*890232f2SAndroid Build Coastguard Worker deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,208*890232f2SAndroid Build Coastguard Worker fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error> 209*890232f2SAndroid Build Coastguard Worker where 210*890232f2SAndroid Build Coastguard Worker V: Visitor<'de>, 211*890232f2SAndroid Build Coastguard Worker { 212*890232f2SAndroid Build Coastguard Worker visitor.visit_char(self.as_u8() as char) 213*890232f2SAndroid Build Coastguard Worker } 214*890232f2SAndroid Build Coastguard Worker deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,215*890232f2SAndroid Build Coastguard Worker fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error> 216*890232f2SAndroid Build Coastguard Worker where 217*890232f2SAndroid Build Coastguard Worker V: Visitor<'de>, 218*890232f2SAndroid Build Coastguard Worker { 219*890232f2SAndroid Build Coastguard Worker visitor.visit_byte_buf(self.get_blob()?.0.to_vec()) 220*890232f2SAndroid Build Coastguard Worker } 221*890232f2SAndroid Build Coastguard Worker deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de>,222*890232f2SAndroid Build Coastguard Worker fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error> 223*890232f2SAndroid Build Coastguard Worker where 224*890232f2SAndroid Build Coastguard Worker V: Visitor<'de>, 225*890232f2SAndroid Build Coastguard Worker { 226*890232f2SAndroid Build Coastguard Worker if self.flexbuffer_type() == FlexBufferType::Null { 227*890232f2SAndroid Build Coastguard Worker visitor.visit_none() 228*890232f2SAndroid Build Coastguard Worker } else { 229*890232f2SAndroid Build Coastguard Worker visitor.visit_some(self) 230*890232f2SAndroid Build Coastguard Worker } 231*890232f2SAndroid Build Coastguard Worker } 232*890232f2SAndroid Build Coastguard Worker deserialize_newtype_struct<V>( self, _name: &'static str, visitor: V, ) -> Result<V::Value, Self::Error> where V: Visitor<'de>,233*890232f2SAndroid Build Coastguard Worker fn deserialize_newtype_struct<V>( 234*890232f2SAndroid Build Coastguard Worker self, 235*890232f2SAndroid Build Coastguard Worker _name: &'static str, 236*890232f2SAndroid Build Coastguard Worker visitor: V, 237*890232f2SAndroid Build Coastguard Worker ) -> Result<V::Value, Self::Error> 238*890232f2SAndroid Build Coastguard Worker where 239*890232f2SAndroid Build Coastguard Worker V: Visitor<'de>, 240*890232f2SAndroid Build Coastguard Worker { 241*890232f2SAndroid Build Coastguard Worker visitor.visit_newtype_struct(self) 242*890232f2SAndroid Build Coastguard Worker } 243*890232f2SAndroid Build Coastguard Worker deserialize_enum<V>( self, _name: &'static str, _variants: &'static [&'static str], visitor: V, ) -> Result<V::Value, Self::Error> where V: Visitor<'de>,244*890232f2SAndroid Build Coastguard Worker fn deserialize_enum<V>( 245*890232f2SAndroid Build Coastguard Worker self, 246*890232f2SAndroid Build Coastguard Worker _name: &'static str, 247*890232f2SAndroid Build Coastguard Worker _variants: &'static [&'static str], 248*890232f2SAndroid Build Coastguard Worker visitor: V, 249*890232f2SAndroid Build Coastguard Worker ) -> Result<V::Value, Self::Error> 250*890232f2SAndroid Build Coastguard Worker where 251*890232f2SAndroid Build Coastguard Worker V: Visitor<'de>, 252*890232f2SAndroid Build Coastguard Worker { 253*890232f2SAndroid Build Coastguard Worker let (variant, value) = match self.fxb_type { 254*890232f2SAndroid Build Coastguard Worker FlexBufferType::String => (self.as_str(), None), 255*890232f2SAndroid Build Coastguard Worker FlexBufferType::Map => { 256*890232f2SAndroid Build Coastguard Worker let m = self.get_map()?; 257*890232f2SAndroid Build Coastguard Worker let variant = m.keys_vector().idx(0).get_key()?; 258*890232f2SAndroid Build Coastguard Worker let value = Some(m.idx(0)); 259*890232f2SAndroid Build Coastguard Worker (variant, value) 260*890232f2SAndroid Build Coastguard Worker } 261*890232f2SAndroid Build Coastguard Worker _ => { 262*890232f2SAndroid Build Coastguard Worker return Err(Error::UnexpectedFlexbufferType { 263*890232f2SAndroid Build Coastguard Worker expected: FlexBufferType::Map, 264*890232f2SAndroid Build Coastguard Worker actual: self.fxb_type, 265*890232f2SAndroid Build Coastguard Worker } 266*890232f2SAndroid Build Coastguard Worker .into()); 267*890232f2SAndroid Build Coastguard Worker } 268*890232f2SAndroid Build Coastguard Worker }; 269*890232f2SAndroid Build Coastguard Worker visitor.visit_enum(EnumReader { variant, value }) 270*890232f2SAndroid Build Coastguard Worker } 271*890232f2SAndroid Build Coastguard Worker } 272