diff options
author | Aaron O'Mullan <aaron.omullan@gmail.com> | 2022-04-24 09:28:46 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-24 09:28:46 -0300 |
commit | 4b7d306a198d020ce2b6fa1c758c71714bfd036c (patch) | |
tree | 10de79efbbd30107d0f04538c351b0765ec97a06 /serde_v8/magic/string_or_buffer.rs | |
parent | 2eb8c3b82fd54027c35c87ccc94797e34e2e95fd (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.rs | 67 |
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) } } |