summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock12
-rw-r--r--core/Cargo.toml2
-rw-r--r--core/lib.rs1
-rw-r--r--serde_v8/src/de.rs10
-rw-r--r--serde_v8/src/lib.rs1
-rw-r--r--serde_v8/src/magic/mod.rs1
-rw-r--r--serde_v8/src/magic/string_or_buffer.rs38
-rw-r--r--serde_v8/src/payload.rs4
-rw-r--r--serde_v8/tests/de.rs16
9 files changed, 73 insertions, 12 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 112f4bcb1..7f6f616a0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -771,7 +771,7 @@ dependencies = [
"rusty_v8",
"serde",
"serde_json",
- "serde_v8 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_v8",
"tokio",
"url",
]
@@ -3337,16 +3337,6 @@ dependencies = [
]
[[package]]
-name = "serde_v8"
-version = "0.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b431c505c5ece0caf45ffa6d089d6da7c675303aa82f8cccb76135bb1bc6a2b0"
-dependencies = [
- "rusty_v8",
- "serde",
-]
-
-[[package]]
name = "sha-1"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/core/Cargo.toml b/core/Cargo.toml
index 3d2c7d335..c39dbf185 100644
--- a/core/Cargo.toml
+++ b/core/Cargo.toml
@@ -24,7 +24,7 @@ pin-project = "1.0.7"
rusty_v8 = "0.32.0"
serde = { version = "1.0.129", features = ["derive"] }
serde_json = { version = "1.0.66", features = ["preserve_order"] }
-serde_v8 = "0.15.0"
+serde_v8 = { version = "0.15.0", path = "../serde_v8" }
url = { version = "2.2.2", features = ["serde"] }
[[example]]
diff --git a/core/lib.rs b/core/lib.rs
index c0419f8ab..889f613df 100644
--- a/core/lib.rs
+++ b/core/lib.rs
@@ -26,6 +26,7 @@ pub use serde_json;
pub use serde_v8;
pub use serde_v8::Buffer as ZeroCopyBuf;
pub use serde_v8::ByteString;
+pub use serde_v8::StringOrBuffer;
pub use url;
pub use crate::async_cancel::CancelFuture;
diff --git a/serde_v8/src/de.rs b/serde_v8/src/de.rs
index 3668a4fd5..d4338a37f 100644
--- a/serde_v8/src/de.rs
+++ b/serde_v8/src/de.rs
@@ -132,6 +132,16 @@ impl<'de, 'a, 'b, 's, 'x> de::Deserializer<'de>
ValueType::String => self.deserialize_string(visitor),
ValueType::Array => self.deserialize_seq(visitor),
ValueType::Object => self.deserialize_map(visitor),
+ // Map to Vec<u8> when deserialized via deserialize_any
+ // e.g: for untagged enums or StringOrBuffer
+ ValueType::ArrayBufferView => {
+ v8::Local::<v8::ArrayBufferView>::try_from(self.input)
+ .and_then(|view| {
+ magic::zero_copy_buf::ZeroCopyBuf::try_new(self.scope, view)
+ })
+ .map_err(|_| Error::ExpectedInteger)
+ .and_then(|zb| visitor.visit_byte_buf(Vec::from(&*zb)))
+ }
}
}
diff --git a/serde_v8/src/lib.rs b/serde_v8/src/lib.rs
index 374a27ce2..d97b1f1af 100644
--- a/serde_v8/src/lib.rs
+++ b/serde_v8/src/lib.rs
@@ -13,6 +13,7 @@ pub use error::{Error, Result};
pub use keys::KeyCache;
pub use magic::buffer::MagicBuffer as Buffer;
pub use magic::bytestring::ByteString;
+pub use magic::string_or_buffer::StringOrBuffer;
pub use magic::Value;
pub use ser::{to_v8, Serializer};
pub use serializable::{Serializable, SerializablePkg};
diff --git a/serde_v8/src/magic/mod.rs b/serde_v8/src/magic/mod.rs
index 00c06fd4c..91a09e2f4 100644
--- a/serde_v8/src/magic/mod.rs
+++ b/serde_v8/src/magic/mod.rs
@@ -2,6 +2,7 @@
pub mod buffer;
pub mod bytestring;
mod field;
+pub mod string_or_buffer;
mod value;
pub mod zero_copy_buf;
diff --git a/serde_v8/src/magic/string_or_buffer.rs b/serde_v8/src/magic/string_or_buffer.rs
new file mode 100644
index 000000000..88a6344c4
--- /dev/null
+++ b/serde_v8/src/magic/string_or_buffer.rs
@@ -0,0 +1,38 @@
+use std::ops::Deref;
+
+#[derive(Debug)]
+pub struct StringOrBuffer(Vec<u8>);
+
+impl Deref for StringOrBuffer {
+ type Target = Vec<u8>;
+ fn deref(&self) -> &Vec<u8> {
+ &self.0
+ }
+}
+
+impl<'de> serde::Deserialize<'de> for StringOrBuffer {
+ fn deserialize<D>(deserializer: D) -> Result<StringOrBuffer, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ StringOrBufferInner::deserialize(deserializer)
+ .map(|x| StringOrBuffer(x.into_bytes()))
+ }
+}
+
+// TODO(@AaronO): explore if we can make this work with ZeroCopyBuf
+#[derive(serde::Deserialize)]
+#[serde(untagged)]
+enum StringOrBufferInner {
+ String(String),
+ Buffer(Vec<u8>),
+}
+
+impl StringOrBufferInner {
+ fn into_bytes(self) -> Vec<u8> {
+ match self {
+ Self::String(s) => s.into_bytes(),
+ Self::Buffer(b) => b,
+ }
+ }
+}
diff --git a/serde_v8/src/payload.rs b/serde_v8/src/payload.rs
index 816158f93..a9fb045e3 100644
--- a/serde_v8/src/payload.rs
+++ b/serde_v8/src/payload.rs
@@ -5,12 +5,14 @@ use rusty_v8 as v8;
// so it can implement Deserialize by itself
// Classifies v8::Values into sub-types
+#[derive(Debug)]
pub enum ValueType {
Null,
Bool,
Number,
String,
Array,
+ ArrayBufferView,
Object,
}
@@ -24,6 +26,8 @@ impl ValueType {
return Self::String;
} else if v.is_array() {
return Self::Array;
+ } else if v.is_array_buffer_view() {
+ return Self::ArrayBufferView;
} else if v.is_object() {
return Self::Object;
} else if v.is_null_or_undefined() {
diff --git a/serde_v8/tests/de.rs b/serde_v8/tests/de.rs
index e036fd683..888bff4f4 100644
--- a/serde_v8/tests/de.rs
+++ b/serde_v8/tests/de.rs
@@ -168,6 +168,22 @@ fn de_map() {
})
}
+#[test]
+fn de_string_or_buffer() {
+ dedo("'hello'", |scope, v| {
+ let sob: serde_v8::StringOrBuffer = serde_v8::from_v8(scope, v).unwrap();
+ assert_eq!(sob.as_slice(), &[0x68, 0x65, 0x6C, 0x6C, 0x6F]);
+ });
+
+ dedo(
+ "(Uint8Array.from([0x68, 0x65, 0x6C, 0x6C, 0x6F]))",
+ |scope, v| {
+ let sob: serde_v8::StringOrBuffer = serde_v8::from_v8(scope, v).unwrap();
+ assert_eq!(sob.as_slice(), &[0x68, 0x65, 0x6C, 0x6C, 0x6F]);
+ },
+ );
+}
+
////
// JSON tests: serde_json::Value compatibility
////