mirror of
https://github.com/denoland/deno.git
synced 2024-11-24 15:19:26 -05:00
feat(serde_v8): StringOrBuffer (#12503)
This commit is contained in:
parent
6a96560986
commit
783b4da48a
9 changed files with 73 additions and 12 deletions
12
Cargo.lock
generated
12
Cargo.lock
generated
|
@ -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",
|
||||
]
|
||||
|
@ -3336,16 +3336,6 @@ dependencies = [
|
|||
"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]]
|
||||
name = "sha-1"
|
||||
version = "0.9.8"
|
||||
|
|
|
@ -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]]
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
pub mod buffer;
|
||||
pub mod bytestring;
|
||||
mod field;
|
||||
pub mod string_or_buffer;
|
||||
mod value;
|
||||
pub mod zero_copy_buf;
|
||||
|
||||
|
|
38
serde_v8/src/magic/string_or_buffer.rs
Normal file
38
serde_v8/src/magic/string_or_buffer.rs
Normal 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,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
////
|
||||
|
|
Loading…
Reference in a new issue