hpl_toolkit/utils/
short_string.rs1use std::io::Read;
2
3use anchor_lang::prelude::*;
4
5#[cfg(feature = "compression")]
6use crate::compression::*;
7
8#[cfg(feature = "schema")]
9use crate::schema::*;
10
11#[cfg_attr(feature = "debug", derive(Debug))]
12#[derive(Clone, Eq, PartialEq)]
13pub struct ShortString(String);
14
15impl ShortString {
16 pub fn new(string: String) -> std::io::Result<Self> {
17 if string.len() > 255 {
18 return Err(std::io::Error::new(
19 std::io::ErrorKind::InvalidInput,
20 "Short string length shall not exceed 255",
21 ));
22 }
23 Ok(Self(string))
24 }
25
26 pub fn new_unchecked(string: String) -> Self {
27 Self::new(string).expect("Short string length shall not exceed 255")
28 }
29
30 pub unsafe fn new_unsafe(string: String) -> Self {
31 Self::new_unchecked(string)
32 }
33
34 pub fn to_string(&self) -> String {
35 self.0.clone()
36 }
37
38 pub fn as_str(&self) -> &str {
39 self.0.as_str()
40 }
41}
42
43impl From<String> for ShortString {
44 fn from(value: String) -> Self {
45 Self::new_unchecked(value)
46 }
47}
48
49impl From<&String> for ShortString {
50 fn from(value: &String) -> Self {
51 Self::new_unchecked(value.to_owned())
52 }
53}
54
55impl Into<String> for ShortString {
56 fn into(self) -> String {
57 self.0
58 }
59}
60
61impl PartialEq<String> for ShortString {
62 fn eq(&self, other: &String) -> bool {
63 self.0 == *other
64 }
65}
66
67impl From<&str> for ShortString {
68 fn from(value: &str) -> Self {
69 Self::new_unchecked(value.to_string())
70 }
71}
72
73impl AnchorSerialize for ShortString {
74 fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
75 let length = self.0.len() as u8;
76 length.serialize(writer)?;
77 writer.write(self.0.as_bytes())?;
78 Ok(())
79 }
80}
81
82impl AnchorDeserialize for ShortString {
83 fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
84 let mut buf: [u8; 1] = [0; 1];
85 let limit = reader.read(&mut buf)?;
86 if limit != 1 {
87 #[cfg(feature = "log")]
88 crate::logger::debug!("limit: {}, Buf: {:?}", limit, buf);
89 return Err(std::io::Error::new(
90 std::io::ErrorKind::InvalidInput,
91 "Unexpected length of input",
92 ));
93 }
94
95 let mut string = String::new();
96 reader.take(buf[0] as u64).read_to_string(&mut string)?;
97 Ok(Self(string))
98 }
99}
100
101#[cfg(feature = "idl-build")]
102impl anchor_lang::IdlBuild for ShortString {
103 fn get_full_path() -> String {
105 format!(
106 "{0}::{1}",
107 "hpl_toolkit::utils::short_string", "ShortString",
108 )
109 }
110}
111
112#[cfg(feature = "compression")]
113impl ToNode for ShortString {
114 fn to_node(&self) -> [u8; 32] {
115 self.0.to_node()
116 }
117}
118
119#[cfg(feature = "schema")]
120impl ToSchema for ShortString {
121 fn schema() -> Schema {
122 String::schema()
123 }
124
125 fn schema_value(&self) -> SchemaValue {
126 self.0.schema_value()
127 }
128}