1use crate::value::Value;
7use crate::value::list::List;
8use crate::value::meta::Meta;
9use crate::value::print::Print;
10use crate::value::tracer::Tracer;
11use bstr::ByteSlice;
12use serde::Deserialize;
13use serde::Serialize;
14use unicode_segmentation::UnicodeSegmentation;
15
16#[derive(Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
17pub struct Bytes {
18 #[serde(default, skip_serializing_if = "Tracer::is_empty")]
19 pub(crate) tracer: Tracer,
20 #[serde(default, skip_serializing_if = "Meta::is_empty")]
21 pub(crate) meta: Meta,
22 #[serde(with = "crate::serde::bytes_as_base64")]
23 pub(crate) data: Vec<u8>,
24}
25
26impl core::fmt::Debug for Bytes {
27 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
28 f.debug_struct("Bytes")
29 .field("tracer", &self.tracer)
30 .field("meta", &self.meta)
31 .field("data", &String::from_utf8_lossy(&self.data))
32 .finish()
33 }
34}
35
36impl core::fmt::Display for Bytes {
37 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
38 f.write_str(&String::from_utf8_lossy(&self.clone().print_syntax()))
39 }
40}
41
42impl From<Vec<u8>> for Bytes {
43 fn from(value: Vec<u8>) -> Self {
44 Self {
45 data: value,
46 ..Default::default()
47 }
48 }
49}
50
51impl Bytes {
52 pub(crate) fn trace<T: Into<Tracer>>(&mut self, tracer: T) {
53 self.tracer.trace(tracer);
54 }
55
56 pub(crate) fn tracer(&self) -> &Tracer {
57 &self.tracer
58 }
59
60 pub fn as_bytes(&self) -> &[u8] {
61 &self.data
62 }
63
64 pub fn as_chars(&self) -> List {
65 self.data
66 .chars()
67 .map(String::from)
68 .map(Value::from)
69 .collect()
70 }
71
72 pub fn is_empty(&self) -> bool {
73 self.data.is_empty()
74 }
75
76 pub fn contains(self, needle: &[u8]) -> bool {
77 match (self.is_empty(), needle.is_empty()) {
78 (false, false) => self.data.windows(needle.len()).any(|w| w == needle),
79 (true, false) => false,
80 (_, true) => true,
81 }
82 }
83
84 pub fn join(self) -> Vec<u8> {
85 self.data
86 }
87
88 pub fn clear(mut self) -> Self {
89 self.data = Vec::default();
90 self
91 }
92
93 pub fn trim(mut self) -> Self {
94 let trim = self.data.trim();
95
96 if self.data.len() != trim.len() {
97 self.data = trim.to_vec();
98 }
99
100 self
101 }
102
103 pub fn first(mut self) -> Bytes {
104 self.data = str::from_utf8(&self.data)
105 .unwrap_or_default()
106 .graphemes(true)
107 .next()
108 .map(|v| v.as_bytes().to_vec())
109 .unwrap_or_default();
110 self
111 }
112
113 pub fn last(mut self) -> Bytes {
114 self.data = str::from_utf8(&self.data)
115 .unwrap_or_default()
116 .graphemes(true)
117 .next_back()
118 .map(|v| v.as_bytes().to_vec())
119 .unwrap_or_default();
120 self
121 }
122
123 pub fn rest(mut self) -> Bytes {
124 self.data = str::from_utf8(&self.data)
125 .unwrap_or_default()
126 .graphemes(true)
127 .skip(1)
128 .collect::<String>()
129 .into_bytes();
130 self
131 }
132
133 pub(crate) fn fold(&mut self, mut value: Self) {
134 match value.meta.get(b"internal-insert") {
135 Some(b"prepend") => {
136 value.data.append(&mut self.data);
137 self.data = value.data;
138 }
139 Some(b"append") => {
140 self.data.append(&mut value.data);
141 }
142 _ => {
143 *self = value;
144 }
145 }
146 }
147}