diff options
Diffstat (limited to 'serde_v8')
-rw-r--r-- | serde_v8/de.rs | 6 | ||||
-rw-r--r-- | serde_v8/error.rs | 1 | ||||
-rw-r--r-- | serde_v8/lib.rs | 1 | ||||
-rw-r--r-- | serde_v8/magic/any_value.rs | 66 | ||||
-rw-r--r-- | serde_v8/magic/mod.rs | 1 | ||||
-rw-r--r-- | serde_v8/payload.rs | 3 | ||||
-rw-r--r-- | serde_v8/ser.rs | 8 |
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)) |