ignite/pstring/
pstring.rs

1use super::compressor::Compressor;
2use super::COMPRESSIONDEFAULT;
3use snap;
4use std::fmt;
5use std::str;
6use std::string::String;
7use std::vec::Vec;
8use str_util::to_bytes;
9
10/// The PointString, a string variant comprised of a Vec<u8> which provides easy access and manipulation of individual
11/// bytes with support for in memory compression of strings.
12#[derive(Debug, Clone)]
13pub struct PString {
14    pub compression: bool,
15    codepoints: Vec<u8>,
16}
17
18// Implement the display trait.
19impl fmt::Display for PString {
20    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21        write!(f, "{}", self.clone().to_string_backend())
22    }
23}
24
25impl PString {
26    /// Create a new, empty PString.
27    #[inline]
28    pub fn new() -> PString {
29        PString {
30            compression: COMPRESSIONDEFAULT,
31            codepoints: Vec::new(),
32        }
33    }
34
35    /// Get a specific char.
36    #[inline]
37    pub fn char_at(&self, index: usize) -> char {
38        let bytes = self.decompress_to_bytes();
39
40        bytes[index] as char
41    }
42
43    /// Create a new PString with a certain preallocated capacity to save reallocations.
44    #[inline]
45    pub fn with_capacity(capacity: usize) -> PString {
46        PString {
47            compression: COMPRESSIONDEFAULT,
48            codepoints: Vec::with_capacity(capacity),
49        }
50    }
51
52    /// Create a new PString with a Vec of bytes.
53    #[inline]
54    pub fn from_bytes(codepoints: Vec<u8>) -> PString {
55        PString {
56            compression: COMPRESSIONDEFAULT,
57            codepoints: Compressor::compress_bytes(codepoints, COMPRESSIONDEFAULT),
58        }
59    }
60
61    /// Set the bytes of an existing PString.
62    #[inline]
63    pub fn set_bytes(&mut self, codepoints: Vec<u8>) {
64        self.codepoints = Compressor::compress_bytes(codepoints, self.compression);
65    }
66
67    /// Set a existing PString to a str.
68    #[inline]
69    pub fn set_str(&mut self, string: &'static str) {
70        self.codepoints = Compressor::compress_bytes(to_bytes::str_to_bytes(string), self.compression);
71    }
72
73    /// Set a existing PString to a str.
74    #[inline]
75    pub fn set_string(&mut self, string: String) {
76        self.codepoints = Compressor::compress_bytes(to_bytes::string_to_bytes(string), self.compression);
77    }
78
79    /// Create a PString from a str pointer.
80    #[inline]
81    pub fn from_str(string: &'static str) -> PString {
82        let returnvalue: PString = PString::from_bytes(to_bytes::str_to_bytes(string));
83
84        returnvalue
85    }
86
87    /// Create a PString from a String.
88    #[inline]
89    pub fn from_string(string: String) -> PString {
90        let returnvalue: PString = PString::from_bytes(to_bytes::string_to_bytes(string));
91
92        returnvalue
93    }
94
95    /// Backend private function to convert to a string.
96    #[inline]
97    fn to_string_backend(&mut self) -> String {
98        let bytes = Compressor::decompress_bytes(self.codepoints.clone(), self.compression);
99
100        String::from_utf8(bytes).unwrap()
101    }
102
103    /// Get the individual bytes that make up a PString.
104    #[inline]
105    pub fn as_bytes(&mut self) -> Vec<u8> {
106        self.decompress_to_bytes()
107    }
108
109    /// Get the individual raw bytes that make up a PString.
110    #[inline]
111    pub fn as_bytes_raw(&self) -> Vec<u8> {
112        self.codepoints.clone()
113    }
114
115    /// Get a Vec of all chars in the pstring.
116    pub fn chars(&self) -> Vec<char> {
117        let mut chararray: Vec<char> = Vec::new();
118        for byte in self.decompress_to_bytes() {
119            chararray.push(byte as char);
120        }
121
122        chararray
123    }
124
125    /// Enable compression.
126    pub fn compress(&mut self) {
127        if self.compression == false {
128            let mut encoder = snap::Encoder::new();
129            self.codepoints = encoder.compress_vec(&self.codepoints[..]).unwrap();
130            self.compression = true;
131        }
132    }
133
134    /// Disable compression.
135    pub fn decompress(&mut self) {
136        if self.compression == true {
137            let mut decoder = snap::Decoder::new();
138            self.codepoints = decoder.decompress_vec(&self.codepoints[..]).unwrap();
139            self.compression = false;
140        }
141    }
142
143    /// Compress a codepoints byte struct.
144    #[allow(dead_code)]
145    #[inline(always)]
146    fn compress_to_bytes(&self) -> Vec<u8> {
147        if self.compression == true {
148            let mut encoder = snap::Encoder::new();
149            return encoder.compress_vec(&self.codepoints[..]).unwrap();
150        }
151
152        self.codepoints.clone()
153    }
154
155    /// Decompress a codepoints byte struct
156    #[allow(dead_code)]
157    #[inline(always)]
158    fn decompress_to_bytes(&self) -> Vec<u8> {
159        if self.compression == true {
160            let mut decoder = snap::Decoder::new();
161            return decoder.decompress_vec(&self.codepoints[..]).unwrap();
162        }
163
164        self.codepoints.clone()
165    }
166
167    /// Autocompress data if enabled.
168    #[allow(dead_code)]
169    #[inline(always)]
170    fn autocompress(&mut self) {
171        if self.compression {
172            let mut encoder = snap::Encoder::new();
173            self.codepoints = encoder.compress_vec(&self.codepoints[..]).unwrap();
174        }
175    }
176
177    /// Autodecompress data if enabled.
178    #[allow(dead_code)]
179    #[inline(always)]
180    fn autodecompress(&mut self) {
181        if self.compression {
182            let mut decoder = snap::Decoder::new();
183            self.codepoints = decoder.decompress_vec(&self.codepoints[..]).unwrap();
184        }
185    }
186}