diff options
author | Aaron O'Mullan <aaron.omullan@gmail.com> | 2021-10-20 15:40:20 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-20 15:40:20 +0200 |
commit | 783b4da48a457818aac174e0b9b0d6b8f1579778 (patch) | |
tree | 152e4d188f4c7ad253f0bfd4ed23b4f4284cb176 | |
parent | 6a9656098671d19b2cbfedfef4db0df6f84735d1 (diff) |
feat(serde_v8): StringOrBuffer (#12503)
-rw-r--r-- | Cargo.lock | 12 | ||||
-rw-r--r-- | core/Cargo.toml | 2 | ||||
-rw-r--r-- | core/lib.rs | 1 | ||||
-rw-r--r-- | serde_v8/src/de.rs | 10 | ||||
-rw-r--r-- | serde_v8/src/lib.rs | 1 | ||||
-rw-r--r-- | serde_v8/src/magic/mod.rs | 1 | ||||
-rw-r--r-- | serde_v8/src/magic/string_or_buffer.rs | 38 | ||||
-rw-r--r-- | serde_v8/src/payload.rs | 4 | ||||
-rw-r--r-- | serde_v8/tests/de.rs | 16 |
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 //// |