turbo_tasks_bytes/
bytes.rs1use std::{
2 ops::Deref,
3 str::{Utf8Error, from_utf8},
4};
5
6use anyhow::Result;
7use bincode::{
8 Decode, Encode,
9 de::Decoder,
10 enc::Encoder,
11 error::{DecodeError, EncodeError},
12 impl_borrow_decode,
13};
14use bytes::Bytes as CBytes;
15
16#[derive(Clone, Debug, Default)]
19#[turbo_tasks::value(transparent, serialization = "custom")]
20pub struct Bytes(#[turbo_tasks(trace_ignore)] CBytes);
21
22impl Bytes {
23 pub fn to_str(&self) -> Result<&'_ str, Utf8Error> {
24 from_utf8(&self.0)
25 }
26}
27
28impl Encode for Bytes {
29 fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
30 self[..].encode(encoder)
31 }
32}
33
34impl<Context> Decode<Context> for Bytes {
35 fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
36 Ok(Bytes(CBytes::from(Vec::<u8>::decode(decoder)?)))
39 }
40}
41
42impl_borrow_decode!(Bytes);
43
44impl Deref for Bytes {
45 type Target = CBytes;
46 fn deref(&self) -> &Self::Target {
47 &self.0
48 }
49}
50
51pub trait IntoBytes: Into<CBytes> {}
56impl IntoBytes for &'static [u8] {}
57impl IntoBytes for &'static str {}
58impl IntoBytes for Vec<u8> {}
59impl IntoBytes for Box<[u8]> {}
60impl IntoBytes for String {}
61
62impl<T: IntoBytes> From<T> for Bytes {
63 fn from(value: T) -> Self {
64 Bytes(value.into())
65 }
66}
67
68impl From<CBytes> for Bytes {
69 fn from(value: CBytes) -> Self {
70 Bytes(value)
71 }
72}
73
74impl From<Bytes> for CBytes {
75 fn from(value: Bytes) -> Self {
76 value.0
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 impl PartialEq<&str> for Bytes {
85 fn eq(&self, other: &&str) -> bool {
86 self.0 == other
87 }
88 }
89
90 #[test]
91 fn into_bytes() {
92 let s = "foo".to_string();
93 assert_eq!(Bytes::from(b"foo" as &'static [u8]), "foo");
94 assert_eq!(Bytes::from("foo"), "foo");
95 assert_eq!(Bytes::from(s.as_bytes().to_vec()), "foo");
96 assert_eq!(Bytes::from(s.as_bytes().to_vec().into_boxed_slice()), "foo");
97 assert_eq!(Bytes::from(s), "foo");
98 }
99
100 #[test]
101 fn bincode() {
102 let s = Bytes::from("test");
103 let c = bincode::config::standard();
104 let decoded: Bytes = bincode::decode_from_slice(&bincode::encode_to_vec(&s, c).unwrap(), c)
105 .unwrap()
106 .0;
107 assert_eq!(decoded, s);
108 }
109
110 #[test]
111 fn from_into() {
112 let b = Bytes::from("foo");
113 let cb = CBytes::from("foo");
114 assert_eq!(Bytes::from(cb), "foo");
115 assert_eq!(CBytes::from(b), "foo");
116 }
117
118 #[test]
119 fn deref() {
120 let b = Bytes::from("foo");
121 assert_eq!(*b, CBytes::from("foo"));
122 }
123
124 #[test]
125 fn to_str() {
126 let cb = Bytes::from("foo");
127 assert_eq!(cb.to_str(), Ok("foo"));
128
129 let b = Bytes::from("💩".as_bytes()[0..3].to_vec());
130 assert!(b.to_str().is_err());
131 }
132}