diff options
author | Aaron O'Mullan <aaron.omullan@gmail.com> | 2022-03-23 21:15:01 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-23 21:15:01 +0100 |
commit | f580134b1e4b75bc0e7579ea30cbf9f8c9ea3459 (patch) | |
tree | 993b60fa35a476fab4fdf43caf22906f3316c9a7 /serde_v8/src/magic/value.rs | |
parent | b82ded84d341cda98821592556804a529638589c (diff) |
cleanup(serde_v8): streamline magic types (#14076)
Formalize magic types and how they're "transerialized", also makes U16String deserializable
Diffstat (limited to 'serde_v8/src/magic/value.rs')
-rw-r--r-- | serde_v8/src/magic/value.rs | 76 |
1 files changed, 23 insertions, 53 deletions
diff --git a/serde_v8/src/magic/value.rs b/serde_v8/src/magic/value.rs index 7bd9a4059..5d844fbda 100644 --- a/serde_v8/src/magic/value.rs +++ b/serde_v8/src/magic/value.rs @@ -1,21 +1,19 @@ // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. -use std::fmt; -use std::marker::PhantomData; - -pub const FIELD: &str = "$__v8_magic_value"; -pub const NAME: &str = "$__v8_magic_Value"; +use crate::magic::transl8::impl_magic; +use crate::magic::transl8::FromV8; +use crate::magic::transl8::ToV8; +use std::mem::transmute; /// serde_v8::Value allows passing through `v8::Value`s untouched -/// when encoding/decoding and allows mixing rust & v8 values in -/// structs, tuples... -/// The implementation mainly breaks down to: -/// 1. Transmuting between u64 <> serde_v8::Value -/// 2. Using special struct/field names to detect these values -/// 3. Then serde "boilerplate" +/// when de/serializing & allows mixing rust & v8 values in structs, tuples... +// +// SAFETY: caveat emptor, the rust-compiler can no longer link lifetimes to their +// original scope, you must take special care in ensuring your handles don't outlive their scope pub struct Value<'s> { pub v8_value: v8::Local<'s, v8::Value>, } +impl_magic!(Value<'_>); impl<'s> From<v8::Local<'s, v8::Value>> for Value<'s> { fn from(v8_value: v8::Local<'s, v8::Value>) -> Self { @@ -29,50 +27,22 @@ impl<'s> From<Value<'s>> for v8::Local<'s, v8::Value> { } } -impl serde::Serialize for Value<'_> { - fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> - where - S: serde::Serializer, - { - use serde::ser::SerializeStruct; - - let mut s = serializer.serialize_struct(NAME, 1)?; - let mv = Value { - v8_value: self.v8_value, - }; - let hack: u64 = unsafe { std::mem::transmute(mv) }; - s.serialize_field(FIELD, &hack)?; - s.end() +impl ToV8 for Value<'_> { + fn to_v8<'a>( + &self, + _scope: &mut v8::HandleScope<'a>, + ) -> Result<v8::Local<'a, v8::Value>, crate::Error> { + // SAFETY: not fully safe, since lifetimes are detached from original scope + Ok(unsafe { transmute(self.v8_value) }) } } -impl<'de, 's> serde::Deserialize<'de> for Value<'s> { - fn deserialize<D>(deserializer: D) -> Result<Value<'s>, D::Error> - where - D: serde::Deserializer<'de>, - { - struct ValueVisitor<'s> { - p1: PhantomData<&'s ()>, - } - - impl<'de, 's> serde::de::Visitor<'de> for ValueVisitor<'s> { - type Value = Value<'s>; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str("a v8::Value") - } - - fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> - where - E: serde::de::Error, - { - let mv: Value<'s> = unsafe { std::mem::transmute(v) }; - Ok(mv) - } - } - - static FIELDS: [&str; 1] = [FIELD]; - let visitor = ValueVisitor { p1: PhantomData }; - deserializer.deserialize_struct(NAME, &FIELDS, visitor) +impl FromV8 for Value<'_> { + fn from_v8( + _scope: &mut v8::HandleScope, + value: v8::Local<v8::Value>, + ) -> Result<Self, crate::Error> { + // SAFETY: not fully safe, since lifetimes are detached from original scope + Ok(unsafe { transmute::<Value, Value>(value.into()) }) } } |