turbo_tasks_bytes/
bytes.rs1use std::{
2 ops::Deref,
3 str::{Utf8Error, from_utf8},
4};
5
6use anyhow::Result;
7use bytes::Bytes as CBytes;
8use serde::{Deserialize, Deserializer, Serialize, Serializer};
9
10#[derive(Clone, Debug, Default)]
13#[turbo_tasks::value(transparent, serialization = "custom")]
14pub struct Bytes(#[turbo_tasks(trace_ignore)] CBytes);
15
16impl Bytes {
17 pub fn to_str(&self) -> Result<&'_ str, Utf8Error> {
18 from_utf8(&self.0)
19 }
20}
21
22impl Serialize for Bytes {
23 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
24 serde_bytes::Bytes::new(&self.0).serialize(serializer)
25 }
26}
27
28impl<'de> Deserialize<'de> for Bytes {
29 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
30 let bytes = serde_bytes::ByteBuf::deserialize(deserializer)?;
31 Ok(Bytes(bytes.into_vec().into()))
32 }
33}
34
35impl Deref for Bytes {
36 type Target = CBytes;
37 fn deref(&self) -> &Self::Target {
38 &self.0
39 }
40}
41
42pub trait IntoBytes: Into<CBytes> {}
46impl IntoBytes for &'static [u8] {}
47impl IntoBytes for &'static str {}
48impl IntoBytes for Vec<u8> {}
49impl IntoBytes for Box<[u8]> {}
50impl IntoBytes for String {}
51
52impl<T: IntoBytes> From<T> for Bytes {
53 fn from(value: T) -> Self {
54 Bytes(value.into())
55 }
56}
57
58impl From<CBytes> for Bytes {
59 fn from(value: CBytes) -> Self {
60 Bytes(value)
61 }
62}
63
64impl From<Bytes> for CBytes {
65 fn from(value: Bytes) -> Self {
66 value.0
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use bytes::Bytes as CBytes;
73 use serde_test::{Token, assert_tokens};
74
75 use super::Bytes;
76 impl PartialEq<&str> for Bytes {
77 fn eq(&self, other: &&str) -> bool {
78 self.0 == other
79 }
80 }
81
82 #[test]
83 fn into_bytes() {
84 let s = "foo".to_string();
85 assert_eq!(Bytes::from(b"foo" as &'static [u8]), "foo");
86 assert_eq!(Bytes::from("foo"), "foo");
87 assert_eq!(Bytes::from(s.as_bytes().to_vec()), "foo");
88 assert_eq!(Bytes::from(s.as_bytes().to_vec().into_boxed_slice()), "foo");
89 assert_eq!(Bytes::from(s), "foo");
90 }
91
92 #[test]
93 fn serde() {
94 let s = Bytes::from("test");
95 assert_tokens(&s, &[Token::Bytes(b"test")])
96 }
97
98 #[test]
99 fn from_into() {
100 let b = Bytes::from("foo");
101 let cb = CBytes::from("foo");
102 assert_eq!(Bytes::from(cb), "foo");
103 assert_eq!(CBytes::from(b), "foo");
104 }
105
106 #[test]
107 fn deref() {
108 let b = Bytes::from("foo");
109 assert_eq!(*b, CBytes::from("foo"));
110 }
111
112 #[test]
113 fn to_str() {
114 let cb = Bytes::from("foo");
115 assert_eq!(cb.to_str(), Ok("foo"));
116
117 let b = Bytes::from("💩".as_bytes()[0..3].to_vec());
118 assert!(b.to_str().is_err());
119 }
120}