summaryrefslogtreecommitdiff
path: root/serde_v8
diff options
context:
space:
mode:
Diffstat (limited to 'serde_v8')
-rw-r--r--serde_v8/de.rs6
-rw-r--r--serde_v8/error.rs1
-rw-r--r--serde_v8/lib.rs1
-rw-r--r--serde_v8/magic/any_value.rs66
-rw-r--r--serde_v8/magic/mod.rs1
-rw-r--r--serde_v8/payload.rs3
-rw-r--r--serde_v8/ser.rs8
7 files changed, 85 insertions, 1 deletions
diff --git a/serde_v8/de.rs b/serde_v8/de.rs
index 6708daa4d..5293a705d 100644
--- a/serde_v8/de.rs
+++ b/serde_v8/de.rs
@@ -13,6 +13,7 @@ use crate::magic::transl8::visit_magic;
use crate::magic::transl8::FromV8;
use crate::magic::transl8::MagicType;
use crate::payload::ValueType;
+use crate::AnyValue;
use crate::BigInt;
use crate::ByteString;
use crate::DetachedBuffer;
@@ -135,6 +136,7 @@ impl<'de, 'a, 'b, 's, 'x> de::Deserializer<'de>
self.deserialize_f64(visitor)
}
}
+ ValueType::BigInt => Err(Error::UnsupportedType),
ValueType::String => self.deserialize_string(visitor),
ValueType::Array => self.deserialize_seq(visitor),
ValueType::Object => self.deserialize_map(visitor),
@@ -172,7 +174,6 @@ impl<'de, 'a, 'b, 's, 'x> de::Deserializer<'de>
{
self.deserialize_f64(visitor)
}
-
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
@@ -355,6 +356,9 @@ impl<'de, 'a, 'b, 's, 'x> de::Deserializer<'de>
magic::Value::MAGIC_NAME => {
visit_magic(visitor, magic::Value::from_v8(self.scope, self.input)?)
}
+ AnyValue::MAGIC_NAME => {
+ visit_magic(visitor, AnyValue::from_v8(self.scope, self.input)?)
+ }
_ => {
// Regular struct
let obj = v8::Local::<v8::Object>::try_from(self.input)
diff --git a/serde_v8/error.rs b/serde_v8/error.rs
index 72d3cc925..e61385946 100644
--- a/serde_v8/error.rs
+++ b/serde_v8/error.rs
@@ -28,6 +28,7 @@ pub enum Error {
ExpectedUtf8,
ExpectedLatin1,
+ UnsupportedType,
LengthMismatch,
}
diff --git a/serde_v8/lib.rs b/serde_v8/lib.rs
index 1d17914bb..26d95c67a 100644
--- a/serde_v8/lib.rs
+++ b/serde_v8/lib.rs
@@ -15,6 +15,7 @@ pub use de::Deserializer;
pub use error::Error;
pub use error::Result;
pub use keys::KeyCache;
+pub use magic::any_value::AnyValue;
pub use magic::bigint::BigInt;
pub use magic::buffer::ZeroCopyBuf;
pub use magic::bytestring::ByteString;
diff --git a/serde_v8/magic/any_value.rs b/serde_v8/magic/any_value.rs
new file mode 100644
index 000000000..31a74cfde
--- /dev/null
+++ b/serde_v8/magic/any_value.rs
@@ -0,0 +1,66 @@
+use num_bigint::BigInt;
+
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+use super::buffer::ZeroCopyBuf;
+use super::transl8::FromV8;
+use super::transl8::ToV8;
+use crate::magic::transl8::impl_magic;
+use crate::Error;
+
+/// An untagged enum type that can be any of number, string, bool, bigint, or
+/// buffer.
+#[derive(Debug)]
+pub enum AnyValue {
+ Buffer(ZeroCopyBuf),
+ String(String),
+ Number(f64),
+ BigInt(BigInt),
+ Bool(bool),
+}
+
+impl_magic!(AnyValue);
+
+impl ToV8 for AnyValue {
+ fn to_v8<'a>(
+ &mut self,
+ scope: &mut v8::HandleScope<'a>,
+ ) -> Result<v8::Local<'a, v8::Value>, crate::Error> {
+ match self {
+ Self::Buffer(buf) => buf.to_v8(scope),
+ Self::String(s) => crate::to_v8(scope, s),
+ Self::Number(num) => crate::to_v8(scope, num),
+ Self::BigInt(bigint) => {
+ crate::to_v8(scope, crate::BigInt::from(bigint.clone()))
+ }
+ Self::Bool(b) => crate::to_v8(scope, b),
+ }
+ }
+}
+
+impl FromV8 for AnyValue {
+ fn from_v8(
+ scope: &mut v8::HandleScope,
+ value: v8::Local<v8::Value>,
+ ) -> Result<Self, crate::Error> {
+ if value.is_string() {
+ let string = crate::from_v8(scope, value)?;
+ Ok(AnyValue::String(string))
+ } else if value.is_number() {
+ let string = crate::from_v8(scope, value)?;
+ Ok(AnyValue::Number(string))
+ } else if value.is_big_int() {
+ let bigint = crate::BigInt::from_v8(scope, value)?;
+ Ok(AnyValue::BigInt(bigint.into()))
+ } else if value.is_array_buffer_view() {
+ let buf = ZeroCopyBuf::from_v8(scope, value)?;
+ Ok(AnyValue::Buffer(buf))
+ } else if value.is_boolean() {
+ let string = crate::from_v8(scope, value)?;
+ Ok(AnyValue::Bool(string))
+ } else {
+ Err(Error::Message(
+ "expected string, number, bigint, ArrayBufferView, boolean".into(),
+ ))
+ }
+ }
+}
diff --git a/serde_v8/magic/mod.rs b/serde_v8/magic/mod.rs
index 9e5064867..3e984527d 100644
--- a/serde_v8/magic/mod.rs
+++ b/serde_v8/magic/mod.rs
@@ -1,4 +1,5 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+pub mod any_value;
pub mod bigint;
pub mod buffer;
pub mod bytestring;
diff --git a/serde_v8/payload.rs b/serde_v8/payload.rs
index 27f12014f..b396ad01d 100644
--- a/serde_v8/payload.rs
+++ b/serde_v8/payload.rs
@@ -9,6 +9,7 @@ pub enum ValueType {
Null,
Bool,
Number,
+ BigInt,
String,
Array,
ArrayBuffer,
@@ -26,6 +27,8 @@ impl ValueType {
return Self::String;
} else if v.is_array() {
return Self::Array;
+ } else if v.is_big_int() {
+ return Self::BigInt;
} else if v.is_array_buffer() {
return Self::ArrayBuffer;
} else if v.is_array_buffer_view() {
diff --git a/serde_v8/ser.rs b/serde_v8/ser.rs
index 6c10f3fb4..74ad9ec10 100644
--- a/serde_v8/ser.rs
+++ b/serde_v8/ser.rs
@@ -14,6 +14,7 @@ use crate::magic::transl8::opaque_recv;
use crate::magic::transl8::MagicType;
use crate::magic::transl8::ToV8;
use crate::magic::transl8::MAGIC_FIELD;
+use crate::AnyValue;
use crate::BigInt;
use crate::ByteString;
use crate::DetachedBuffer;
@@ -274,6 +275,7 @@ pub enum StructSerializers<'a, 'b, 'c> {
ExternalPointer(MagicalSerializer<'a, 'b, 'c, magic::ExternalPointer>),
Magic(MagicalSerializer<'a, 'b, 'c, magic::Value<'a>>),
ZeroCopyBuf(MagicalSerializer<'a, 'b, 'c, ZeroCopyBuf>),
+ MagicAnyValue(MagicalSerializer<'a, 'b, 'c, AnyValue>),
MagicDetached(MagicalSerializer<'a, 'b, 'c, DetachedBuffer>),
MagicByteString(MagicalSerializer<'a, 'b, 'c, ByteString>),
MagicU16String(MagicalSerializer<'a, 'b, 'c, U16String>),
@@ -295,6 +297,7 @@ impl<'a, 'b, 'c> ser::SerializeStruct for StructSerializers<'a, 'b, 'c> {
StructSerializers::ExternalPointer(s) => s.serialize_field(key, value),
StructSerializers::Magic(s) => s.serialize_field(key, value),
StructSerializers::ZeroCopyBuf(s) => s.serialize_field(key, value),
+ StructSerializers::MagicAnyValue(s) => s.serialize_field(key, value),
StructSerializers::MagicDetached(s) => s.serialize_field(key, value),
StructSerializers::MagicByteString(s) => s.serialize_field(key, value),
StructSerializers::MagicU16String(s) => s.serialize_field(key, value),
@@ -311,6 +314,7 @@ impl<'a, 'b, 'c> ser::SerializeStruct for StructSerializers<'a, 'b, 'c> {
StructSerializers::ExternalPointer(s) => s.end(),
StructSerializers::Magic(s) => s.end(),
StructSerializers::ZeroCopyBuf(s) => s.end(),
+ StructSerializers::MagicAnyValue(s) => s.end(),
StructSerializers::MagicDetached(s) => s.end(),
StructSerializers::MagicByteString(s) => s.end(),
StructSerializers::MagicU16String(s) => s.end(),
@@ -588,6 +592,10 @@ impl<'a, 'b, 'c> ser::Serializer for Serializer<'a, 'b, 'c> {
let m = MagicalSerializer::<ZeroCopyBuf>::new(self.scope);
Ok(StructSerializers::ZeroCopyBuf(m))
}
+ AnyValue::MAGIC_NAME => {
+ let m = MagicalSerializer::<AnyValue>::new(self.scope);
+ Ok(StructSerializers::MagicAnyValue(m))
+ }
DetachedBuffer::MAGIC_NAME => {
let m = MagicalSerializer::<DetachedBuffer>::new(self.scope);
Ok(StructSerializers::MagicDetached(m))