summaryrefslogtreecommitdiff
path: root/serde_v8/magic/string_or_buffer.rs
diff options
context:
space:
mode:
authorAaron O'Mullan <aaron.omullan@gmail.com>2022-04-24 09:28:46 -0300
committerGitHub <noreply@github.com>2022-04-24 09:28:46 -0300
commit4b7d306a198d020ce2b6fa1c758c71714bfd036c (patch)
tree10de79efbbd30107d0f04538c351b0765ec97a06 /serde_v8/magic/string_or_buffer.rs
parent2eb8c3b82fd54027c35c87ccc94797e34e2e95fd (diff)
perf(serde_v8): zero-copy StringOrBuffer (#14381)
Diffstat (limited to 'serde_v8/magic/string_or_buffer.rs')
-rw-r--r--serde_v8/magic/string_or_buffer.rs67
1 files changed, 36 insertions, 31 deletions
diff --git a/serde_v8/magic/string_or_buffer.rs b/serde_v8/magic/string_or_buffer.rs
index edde2adcd..e04cb1a93 100644
--- a/serde_v8/magic/string_or_buffer.rs
+++ b/serde_v8/magic/string_or_buffer.rs
@@ -1,45 +1,50 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+use super::buffer::MagicBuffer;
+use super::transl8::{FromV8, ToV8};
+use crate::magic::transl8::impl_magic;
+use crate::Error;
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
- }
+pub enum StringOrBuffer {
+ Buffer(MagicBuffer),
+ String(String),
}
-impl StringOrBuffer {
- pub fn into_bytes(self) -> Vec<u8> {
- self.0
- }
-}
+impl_magic!(StringOrBuffer);
-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()))
+impl Deref for StringOrBuffer {
+ type Target = [u8];
+ fn deref(&self) -> &Self::Target {
+ match self {
+ Self::Buffer(b) => b.as_ref(),
+ Self::String(s) => s.as_bytes(),
+ }
}
}
-// TODO(@AaronO): explore if we can make this work with ZeroCopyBuf
-#[derive(serde::Deserialize)]
-#[serde(untagged)]
-enum StringOrBufferInner {
- #[serde(with = "serde_bytes")]
- Buffer(Vec<u8>),
- String(String),
+impl ToV8 for StringOrBuffer {
+ fn to_v8<'a>(
+ &self,
+ scope: &mut v8::HandleScope<'a>,
+ ) -> Result<v8::Local<'a, v8::Value>, crate::Error> {
+ match self {
+ Self::Buffer(buf) => crate::to_v8(scope, buf),
+ Self::String(s) => crate::to_v8(scope, s),
+ }
+ }
}
-impl StringOrBufferInner {
- fn into_bytes(self) -> Vec<u8> {
- match self {
- Self::String(s) => s.into_bytes(),
- Self::Buffer(b) => b,
+impl FromV8 for StringOrBuffer {
+ fn from_v8(
+ scope: &mut v8::HandleScope,
+ value: v8::Local<v8::Value>,
+ ) -> Result<Self, crate::Error> {
+ if let Ok(buf) = MagicBuffer::from_v8(scope, value) {
+ return Ok(Self::Buffer(buf));
+ } else if let Ok(s) = crate::from_v8(scope, value) {
+ return Ok(Self::String(s));
}
+ Err(Error::ExpectedBuffer)
}
}