1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-21 13:00:36 -05:00

feat(serde_v8): StringOrBuffer (#12503)

This commit is contained in:
Aaron O'Mullan 2021-10-20 15:40:20 +02:00 committed by GitHub
parent 6a96560986
commit 783b4da48a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 73 additions and 12 deletions

12
Cargo.lock generated
View file

@ -771,7 +771,7 @@ dependencies = [
"rusty_v8", "rusty_v8",
"serde", "serde",
"serde_json", "serde_json",
"serde_v8 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde_v8",
"tokio", "tokio",
"url", "url",
] ]
@ -3336,16 +3336,6 @@ dependencies = [
"serde_json", "serde_json",
] ]
[[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]] [[package]]
name = "sha-1" name = "sha-1"
version = "0.9.8" version = "0.9.8"

View file

@ -24,7 +24,7 @@ pin-project = "1.0.7"
rusty_v8 = "0.32.0" rusty_v8 = "0.32.0"
serde = { version = "1.0.129", features = ["derive"] } serde = { version = "1.0.129", features = ["derive"] }
serde_json = { version = "1.0.66", features = ["preserve_order"] } 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"] } url = { version = "2.2.2", features = ["serde"] }
[[example]] [[example]]

View file

@ -26,6 +26,7 @@ pub use serde_json;
pub use serde_v8; pub use serde_v8;
pub use serde_v8::Buffer as ZeroCopyBuf; pub use serde_v8::Buffer as ZeroCopyBuf;
pub use serde_v8::ByteString; pub use serde_v8::ByteString;
pub use serde_v8::StringOrBuffer;
pub use url; pub use url;
pub use crate::async_cancel::CancelFuture; pub use crate::async_cancel::CancelFuture;

View file

@ -132,6 +132,16 @@ impl<'de, 'a, 'b, 's, 'x> de::Deserializer<'de>
ValueType::String => self.deserialize_string(visitor), ValueType::String => self.deserialize_string(visitor),
ValueType::Array => self.deserialize_seq(visitor), ValueType::Array => self.deserialize_seq(visitor),
ValueType::Object => self.deserialize_map(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)))
}
} }
} }

View file

@ -13,6 +13,7 @@ pub use error::{Error, Result};
pub use keys::KeyCache; pub use keys::KeyCache;
pub use magic::buffer::MagicBuffer as Buffer; pub use magic::buffer::MagicBuffer as Buffer;
pub use magic::bytestring::ByteString; pub use magic::bytestring::ByteString;
pub use magic::string_or_buffer::StringOrBuffer;
pub use magic::Value; pub use magic::Value;
pub use ser::{to_v8, Serializer}; pub use ser::{to_v8, Serializer};
pub use serializable::{Serializable, SerializablePkg}; pub use serializable::{Serializable, SerializablePkg};

View file

@ -2,6 +2,7 @@
pub mod buffer; pub mod buffer;
pub mod bytestring; pub mod bytestring;
mod field; mod field;
pub mod string_or_buffer;
mod value; mod value;
pub mod zero_copy_buf; pub mod zero_copy_buf;

View file

@ -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,
}
}
}

View file

@ -5,12 +5,14 @@ use rusty_v8 as v8;
// so it can implement Deserialize by itself // so it can implement Deserialize by itself
// Classifies v8::Values into sub-types // Classifies v8::Values into sub-types
#[derive(Debug)]
pub enum ValueType { pub enum ValueType {
Null, Null,
Bool, Bool,
Number, Number,
String, String,
Array, Array,
ArrayBufferView,
Object, Object,
} }
@ -24,6 +26,8 @@ impl ValueType {
return Self::String; return Self::String;
} else if v.is_array() { } else if v.is_array() {
return Self::Array; return Self::Array;
} else if v.is_array_buffer_view() {
return Self::ArrayBufferView;
} else if v.is_object() { } else if v.is_object() {
return Self::Object; return Self::Object;
} else if v.is_null_or_undefined() { } else if v.is_null_or_undefined() {

View file

@ -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 // JSON tests: serde_json::Value compatibility
//// ////