summaryrefslogtreecommitdiff
path: root/serde_v8/src/magic/value.rs
diff options
context:
space:
mode:
authorAaron O'Mullan <aaron.omullan@gmail.com>2022-03-23 21:15:01 +0100
committerGitHub <noreply@github.com>2022-03-23 21:15:01 +0100
commitf580134b1e4b75bc0e7579ea30cbf9f8c9ea3459 (patch)
tree993b60fa35a476fab4fdf43caf22906f3316c9a7 /serde_v8/src/magic/value.rs
parentb82ded84d341cda98821592556804a529638589c (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.rs76
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()) })
}
}