diff options
author | Aaron O'Mullan <aaron.omullan@gmail.com> | 2021-04-18 14:55:41 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-18 14:55:41 +0200 |
commit | 2538de9ceda43a2d1edab3a12778d1ff7c7f0c60 (patch) | |
tree | 4b4a746aa687ffa59edd0010ea2e433468affbf3 | |
parent | 733a00030582375c43fa156e978f25df6ecc9e9a (diff) |
refactor(serde_v8): move magic code to subfolder and minor cleanup (#10230)
-rw-r--r-- | serde_v8/src/magic/field.rs | 143 | ||||
-rw-r--r-- | serde_v8/src/magic/mod.rs | 5 | ||||
-rw-r--r-- | serde_v8/src/magic/value.rs (renamed from serde_v8/src/magic.rs) | 0 | ||||
-rw-r--r-- | serde_v8/src/ser.rs | 161 |
4 files changed, 156 insertions, 153 deletions
diff --git a/serde_v8/src/magic/field.rs b/serde_v8/src/magic/field.rs new file mode 100644 index 000000000..20a387d43 --- /dev/null +++ b/serde_v8/src/magic/field.rs @@ -0,0 +1,143 @@ +use crate::error::{Error, Result}; +use serde::ser::{Impossible, Serialize, Serializer}; + +/// All serde_v8 "magic" values are reduced to structs with 1 or 2 u64 fields +/// assuming usize==u64, most types are simply a pointer or pointer+len (e.g: Box<T>) +pub type TransmutedField = u64; +pub type FieldResult = Result<TransmutedField>; + +macro_rules! not_reachable { + ($($name:ident($ty:ty);)*) => { + $(fn $name(self, _v: $ty) -> FieldResult { + unreachable!(); + })* + }; +} + +/// FieldSerializer is a simple serde::Serializer that only returns u64s +/// it allows the "magic" struct serializers to obtain the transmuted field values +pub struct FieldSerializer {} + +impl Serializer for FieldSerializer { + type Ok = TransmutedField; + type Error = Error; + + type SerializeSeq = Impossible<TransmutedField, Error>; + type SerializeTuple = Impossible<TransmutedField, Error>; + type SerializeTupleStruct = Impossible<TransmutedField, Error>; + type SerializeTupleVariant = Impossible<TransmutedField, Error>; + type SerializeMap = Impossible<TransmutedField, Error>; + type SerializeStruct = Impossible<TransmutedField, Error>; + type SerializeStructVariant = Impossible<TransmutedField, Error>; + + fn serialize_u64(self, transmuted_field: u64) -> FieldResult { + Ok(transmuted_field) + } + + not_reachable! { + serialize_i8(i8); + serialize_i16(i16); + serialize_i32(i32); + serialize_i64(i64); + serialize_u8(u8); + serialize_u16(u16); + serialize_u32(u32); + // serialize_u64(TransmutedField); the chosen one + serialize_f32(f32); + serialize_f64(f64); + serialize_bool(bool); + serialize_char(char); + serialize_str(&str); + serialize_bytes(&[u8]); + } + + fn serialize_none(self) -> FieldResult { + unreachable!(); + } + + fn serialize_some<T: ?Sized + Serialize>(self, _value: &T) -> FieldResult { + unreachable!(); + } + + fn serialize_unit(self) -> FieldResult { + unreachable!(); + } + + fn serialize_unit_struct(self, _name: &'static str) -> FieldResult { + unreachable!(); + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> FieldResult { + unreachable!(); + } + + fn serialize_newtype_struct<T: ?Sized + Serialize>( + self, + _name: &'static str, + _value: &T, + ) -> FieldResult { + unreachable!(); + } + + fn serialize_newtype_variant<T: ?Sized + Serialize>( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> FieldResult { + unreachable!(); + } + fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> { + unreachable!(); + } + + fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> { + unreachable!(); + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleStruct> { + unreachable!(); + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleVariant> { + unreachable!(); + } + + fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> { + unreachable!(); + } + + fn serialize_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeStruct> { + unreachable!(); + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeStructVariant> { + unreachable!(); + } +} diff --git a/serde_v8/src/magic/mod.rs b/serde_v8/src/magic/mod.rs new file mode 100644 index 000000000..c34847031 --- /dev/null +++ b/serde_v8/src/magic/mod.rs @@ -0,0 +1,5 @@ +mod field; +mod value; + +pub use field::FieldSerializer; +pub use value::{Value, FIELD, NAME}; diff --git a/serde_v8/src/magic.rs b/serde_v8/src/magic/value.rs index 2cb622466..2cb622466 100644 --- a/serde_v8/src/magic.rs +++ b/serde_v8/src/magic/value.rs diff --git a/serde_v8/src/ser.rs b/serde_v8/src/ser.rs index e37647053..bc0dfaa22 100644 --- a/serde_v8/src/ser.rs +++ b/serde_v8/src/ser.rs @@ -1,7 +1,7 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. use rusty_v8 as v8; use serde::ser; -use serde::ser::{Impossible, Serialize}; +use serde::ser::Serialize; use std::cell::RefCell; @@ -197,12 +197,11 @@ impl<'a, 'b, 'c> ser::SerializeStruct for ObjectSerializer<'a, 'b, 'c> { } } -pub struct MagicSerializer<'a, 'b, 'c> { - scope: ScopePtr<'a, 'b, 'c>, +pub struct MagicSerializer<'a> { v8_value: Option<v8::Local<'a, v8::Value>>, } -impl<'a, 'b, 'c> ser::SerializeStruct for MagicSerializer<'a, 'b, 'c> { +impl<'a> ser::SerializeStruct for MagicSerializer<'a> { type Ok = JsValue<'a>; type Error = Error; @@ -214,8 +213,9 @@ impl<'a, 'b, 'c> ser::SerializeStruct for MagicSerializer<'a, 'b, 'c> { if key != magic::FIELD { unreachable!(); } - let v8_value = value.serialize(MagicTransmuter { _scope: self.scope })?; - self.v8_value = Some(v8_value); + let transmuted: u64 = value.serialize(magic::FieldSerializer {})?; + let mv: magic::Value<'a> = unsafe { std::mem::transmute(transmuted) }; + self.v8_value = Some(mv.v8_value); Ok(()) } @@ -226,7 +226,7 @@ impl<'a, 'b, 'c> ser::SerializeStruct for MagicSerializer<'a, 'b, 'c> { // Dispatches between magic and regular struct serializers pub enum StructSerializers<'a, 'b, 'c> { - Magic(MagicSerializer<'a, 'b, 'c>), + Magic(MagicSerializer<'a>), Regular(ObjectSerializer<'a, 'b, 'c>), } @@ -464,10 +464,7 @@ impl<'a, 'b, 'c> ser::Serializer for Serializer<'a, 'b, 'c> { _len: usize, ) -> Result<Self::SerializeStruct> { if name == magic::NAME { - let m = MagicSerializer { - scope: self.scope, - v8_value: None, - }; + let m: MagicSerializer<'a> = MagicSerializer { v8_value: None }; return Ok(StructSerializers::Magic(m)); } let o = ObjectSerializer::new(self.scope); @@ -486,145 +483,3 @@ impl<'a, 'b, 'c> ser::Serializer for Serializer<'a, 'b, 'c> { Ok(VariantSerializer::new(scope, variant, x)) } } - -macro_rules! not_reachable { - ($($name:ident($ty:ty, $lt:lifetime);)*) => { - $(fn $name(self, _v: $ty) -> JsResult<$lt> { - unreachable!(); - })* - }; -} - -/// A VERY hackish serde::Serializer -/// that exists solely to transmute a u64 to a serde_v8::Value -struct MagicTransmuter<'a, 'b, 'c> { - _scope: ScopePtr<'a, 'b, 'c>, -} - -impl<'a, 'b, 'c> ser::Serializer for MagicTransmuter<'a, 'b, 'c> { - type Ok = v8::Local<'a, v8::Value>; - type Error = Error; - - type SerializeSeq = Impossible<v8::Local<'a, v8::Value>, Error>; - type SerializeTuple = Impossible<v8::Local<'a, v8::Value>, Error>; - type SerializeTupleStruct = Impossible<v8::Local<'a, v8::Value>, Error>; - type SerializeTupleVariant = Impossible<v8::Local<'a, v8::Value>, Error>; - type SerializeMap = Impossible<v8::Local<'a, v8::Value>, Error>; - type SerializeStruct = Impossible<v8::Local<'a, v8::Value>, Error>; - type SerializeStructVariant = Impossible<v8::Local<'a, v8::Value>, Error>; - - // The only serialize method for this hackish struct - fn serialize_u64(self, v: u64) -> JsResult<'a> { - let mv: magic::Value = unsafe { std::mem::transmute(v) }; - Ok(mv.v8_value) - } - - not_reachable! { - serialize_i8(i8, 'a); - serialize_i16(i16, 'a); - serialize_i32(i32, 'a); - serialize_i64(i64, 'a); - serialize_u8(u8, 'a); - serialize_u16(u16, 'a); - serialize_u32(u32, 'a); - // serialize_u64(u64, 'a); the chosen one - serialize_f32(f32, 'a); - serialize_f64(f64, 'a); - serialize_bool(bool, 'a); - serialize_char(char, 'a); - serialize_str(&str, 'a); - serialize_bytes(&[u8], 'a); - } - - fn serialize_none(self) -> JsResult<'a> { - unreachable!(); - } - - fn serialize_some<T: ?Sized + Serialize>(self, _value: &T) -> JsResult<'a> { - unreachable!(); - } - - fn serialize_unit(self) -> JsResult<'a> { - unreachable!(); - } - - fn serialize_unit_struct(self, _name: &'static str) -> JsResult<'a> { - unreachable!(); - } - - /// For compatibility with serde-json, serialises unit variants as "Variant" strings. - fn serialize_unit_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - ) -> JsResult<'a> { - unreachable!(); - } - - fn serialize_newtype_struct<T: ?Sized + Serialize>( - self, - _name: &'static str, - _value: &T, - ) -> JsResult<'a> { - unreachable!(); - } - - fn serialize_newtype_variant<T: ?Sized + Serialize>( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _value: &T, - ) -> JsResult<'a> { - unreachable!(); - } - fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> { - unreachable!(); - } - - fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> { - unreachable!(); - } - - fn serialize_tuple_struct( - self, - _name: &'static str, - _len: usize, - ) -> Result<Self::SerializeTupleStruct> { - unreachable!(); - } - - fn serialize_tuple_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _len: usize, - ) -> Result<Self::SerializeTupleVariant> { - unreachable!(); - } - - fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> { - unreachable!(); - } - - /// Serialises Rust typed structs into plain JS objects. - fn serialize_struct( - self, - _name: &'static str, - _len: usize, - ) -> Result<Self::SerializeStruct> { - unreachable!(); - } - - fn serialize_struct_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _len: usize, - ) -> Result<Self::SerializeStructVariant> { - unreachable!(); - } -} |