summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron O'Mullan <aaron.omullan@gmail.com>2021-04-18 14:55:41 +0200
committerGitHub <noreply@github.com>2021-04-18 14:55:41 +0200
commit2538de9ceda43a2d1edab3a12778d1ff7c7f0c60 (patch)
tree4b4a746aa687ffa59edd0010ea2e433468affbf3
parent733a00030582375c43fa156e978f25df6ecc9e9a (diff)
refactor(serde_v8): move magic code to subfolder and minor cleanup (#10230)
-rw-r--r--serde_v8/src/magic/field.rs143
-rw-r--r--serde_v8/src/magic/mod.rs5
-rw-r--r--serde_v8/src/magic/value.rs (renamed from serde_v8/src/magic.rs)0
-rw-r--r--serde_v8/src/ser.rs161
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!();
- }
-}