konjure_sdk/data/
buffer.rs1use alloc::{string::String, sync::Arc, vec::Vec};
2use core::{fmt, ops::Deref};
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4
5use super::DataError;
6
7#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
9pub struct Str(Arc<str>);
10
11impl Str {
12 pub fn as_str(&self) -> &str {
14 &self.0
15 }
16
17 pub fn slice(&self, start: usize, end: usize) -> Result<Self, DataError> {
22 self.0
23 .get(start..end)
24 .map(Self::from)
25 .ok_or(DataError::Bounds)
26 }
27
28 pub fn byte_len(&self) -> usize {
30 self.0.len()
31 }
32}
33
34impl From<&str> for Str {
35 fn from(value: &str) -> Self {
36 Self(Arc::from(value))
37 }
38}
39
40impl From<String> for Str {
41 fn from(value: String) -> Self {
42 Self(Arc::from(value))
43 }
44}
45
46impl Deref for Str {
47 type Target = str;
48 fn deref(&self) -> &Self::Target {
49 self.as_str()
50 }
51}
52
53impl fmt::Display for Str {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 f.write_str(self.as_str())
56 }
57}
58
59impl Serialize for Str {
60 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
61 serializer.serialize_str(self.as_str())
62 }
63}
64
65impl<'de> Deserialize<'de> for Str {
66 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
67 String::deserialize(deserializer).map(Self::from)
68 }
69}
70
71#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
73pub struct Bin(Arc<[u8]>);
74
75impl Bin {
76 pub fn as_bytes(&self) -> &[u8] {
78 &self.0
79 }
80
81 pub fn slice(&self, start: usize, end: usize) -> Result<Self, DataError> {
86 self.0
87 .get(start..end)
88 .map(Self::from)
89 .ok_or(DataError::Bounds)
90 }
91
92 pub fn byte_len(&self) -> usize {
94 self.0.len()
95 }
96}
97
98impl From<&[u8]> for Bin {
99 fn from(value: &[u8]) -> Self {
100 Self(Arc::from(value))
101 }
102}
103
104impl From<Vec<u8>> for Bin {
105 fn from(value: Vec<u8>) -> Self {
106 Self(Arc::from(value))
107 }
108}
109
110impl Deref for Bin {
111 type Target = [u8];
112 fn deref(&self) -> &Self::Target {
113 self.as_bytes()
114 }
115}
116
117impl Serialize for Bin {
118 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
119 serializer.serialize_bytes(self.as_bytes())
120 }
121}
122
123impl<'de> Deserialize<'de> for Bin {
124 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
125 Vec::<u8>::deserialize(deserializer).map(Self::from)
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132
133 #[test]
134 fn immutable_buffers_share_clones_and_validate_text_boundaries() {
135 let text = Str::from("λx");
136 let copy = text.clone();
137 assert!(Arc::ptr_eq(&text.0, ©.0));
138 assert_eq!(text.slice(0, 1), Err(DataError::Bounds));
139 assert_eq!(text.slice(0, 2).unwrap().as_str(), "λ");
140 let bytes = Bin::from(alloc::vec![0, 255, 42]);
141 assert!(Arc::ptr_eq(&bytes.0, &bytes.clone().0));
142 let json = serde_json::to_string(&bytes).unwrap();
143 assert_eq!(serde_json::from_str::<Bin>(&json).unwrap(), bytes);
144 }
145}