serde_v8/magic/
bytestring.rs1use std::mem::size_of;
4use std::ops::Deref;
5use std::ops::DerefMut;
6
7use smallvec::SmallVec;
8
9use super::transl8::FromV8;
10use super::transl8::ToV8;
11use crate::Error;
12use crate::magic::transl8::impl_magic;
13
14const USIZE2X: usize = size_of::<usize>() * 2;
15
16#[derive(PartialEq, Eq, Clone, Debug, Default)]
17pub struct ByteString(SmallVec<[u8; USIZE2X]>);
18impl_magic!(ByteString);
19
20impl Deref for ByteString {
21 type Target = SmallVec<[u8; USIZE2X]>;
22
23 fn deref(&self) -> &Self::Target {
24 &self.0
25 }
26}
27
28impl DerefMut for ByteString {
29 fn deref_mut(&mut self) -> &mut Self::Target {
30 &mut self.0
31 }
32}
33
34impl AsRef<[u8]> for ByteString {
35 fn as_ref(&self) -> &[u8] {
36 &self.0
37 }
38}
39
40impl AsMut<[u8]> for ByteString {
41 fn as_mut(&mut self) -> &mut [u8] {
42 &mut self.0
43 }
44}
45
46const _: () =
51 assert!(size_of::<Vec<u8>>() == size_of::<SmallVec<[u8; USIZE2X]>>());
52
53impl ToV8 for ByteString {
54 fn to_v8<'scope, 'i>(
55 &self,
56 scope: &mut v8::PinScope<'scope, 'i>,
57 ) -> Result<v8::Local<'scope, v8::Value>, crate::Error> {
58 let v =
59 v8::String::new_from_one_byte(scope, self, v8::NewStringType::Normal)
60 .unwrap();
61 Ok(v.into())
62 }
63}
64
65impl FromV8 for ByteString {
66 fn from_v8<'scope, 'i>(
67 scope: &mut v8::PinScope,
68 value: v8::Local<'scope, v8::Value>,
69 ) -> Result<Self, crate::Error> {
70 let v8str = v8::Local::<v8::String>::try_from(value)
71 .map_err(|_| Error::ExpectedString(value.type_repr()))?;
72 if !v8str.contains_only_onebyte() {
73 return Err(Error::ExpectedLatin1);
74 }
75 let len = v8str.length();
76 let mut buffer = SmallVec::with_capacity(len);
77 #[allow(clippy::uninit_vec)]
78 unsafe {
81 buffer.set_len(len);
82 v8str.write_one_byte_v2(scope, 0, &mut buffer, v8::WriteFlags::empty());
83 }
84 Ok(Self(buffer))
85 }
86}
87
88impl From<Vec<u8>> for ByteString {
92 fn from(vec: Vec<u8>) -> Self {
93 ByteString(SmallVec::from_vec(vec))
94 }
95}
96
97#[allow(clippy::from_over_into)]
98impl Into<Vec<u8>> for ByteString {
99 fn into(self) -> Vec<u8> {
100 self.0.into_vec()
101 }
102}
103
104impl From<&[u8]> for ByteString {
105 fn from(s: &[u8]) -> Self {
106 ByteString(SmallVec::from_slice(s))
107 }
108}
109
110impl From<&str> for ByteString {
111 fn from(s: &str) -> Self {
112 let v: Vec<u8> = s.into();
113 ByteString::from(v)
114 }
115}
116
117impl From<String> for ByteString {
118 fn from(s: String) -> Self {
119 ByteString::from(s.into_bytes())
120 }
121}