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> {}
55impl IntoBytes for &'static [u8] {}
56impl IntoBytes for &'static str {}
57impl IntoBytes for Vec<u8> {}
58impl IntoBytes for Box<[u8]> {}
59impl IntoBytes for String {}
60
61impl<T: IntoBytes> From<T> for Bytes {
62 fn from(value: T) -> Self {
63 Bytes(value.into())
64 }
65}
66
67impl From<CBytes> for Bytes {
68 fn from(value: CBytes) -> Self {
69 Bytes(value)
70 }
71}
72
73impl From<Bytes> for CBytes {
74 fn from(value: Bytes) -> Self {
75 value.0
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 impl PartialEq<&str> for Bytes {
84 fn eq(&self, other: &&str) -> bool {
85 self.0 == other
86 }
87 }
88
89 #[test]
90 fn into_bytes() {
91 let s = "foo".to_string();
92 assert_eq!(Bytes::from(b"foo" as &'static [u8]), "foo");
93 assert_eq!(Bytes::from("foo"), "foo");
94 assert_eq!(Bytes::from(s.as_bytes().to_vec()), "foo");
95 assert_eq!(Bytes::from(s.as_bytes().to_vec().into_boxed_slice()), "foo");
96 assert_eq!(Bytes::from(s), "foo");
97 }
98
99 #[test]
100 fn bincode() {
101 let s = Bytes::from("test");
102 let c = bincode::config::standard();
103 let decoded: Bytes = bincode::decode_from_slice(&bincode::encode_to_vec(&s, c).unwrap(), c)
104 .unwrap()
105 .0;
106 assert_eq!(decoded, s);
107 }
108
109 #[test]
110 fn from_into() {
111 let b = Bytes::from("foo");
112 let cb = CBytes::from("foo");
113 assert_eq!(Bytes::from(cb), "foo");
114 assert_eq!(CBytes::from(b), "foo");
115 }
116
117 #[test]
118 fn deref() {
119 let b = Bytes::from("foo");
120 assert_eq!(*b, CBytes::from("foo"));
121 }
122
123 #[test]
124 fn to_str() {
125 let cb = Bytes::from("foo");
126 assert_eq!(cb.to_str(), Ok("foo"));
127
128 let b = Bytes::from("💩".as_bytes()[0..3].to_vec());
129 assert!(b.to_str().is_err());
130 }
131}