taos_query/util/
mod.rs

1mod inline_bytes;
2mod inline_json;
3mod inline_nchar;
4mod inline_str;
5
6pub mod hex;
7mod inline_read;
8mod inline_write;
9
10use std::{
11    collections::BTreeMap,
12    io::{Read, Write},
13};
14
15use tokio::io::{AsyncRead, AsyncWrite};
16
17pub use inline_bytes::InlineBytes;
18pub use inline_json::InlineJson;
19pub use inline_nchar::InlineNChar;
20pub use inline_str::InlineStr;
21
22pub use inline_read::AsyncInlinableRead;
23pub use inline_write::AsyncInlinableWrite;
24
25use crate::{RawError, RawResult};
26
27#[derive(Debug)]
28pub struct Edition {
29    pub edition: String,
30    pub expired: bool,
31}
32
33impl Edition {
34    pub fn new(edition: impl Into<String>, expired: bool) -> Self {
35        Self {
36            edition: edition.into(),
37            expired,
38        }
39    }
40    pub fn is_enterprise_edition(&self) -> bool {
41        match (self.edition.as_str(), self.expired) {
42            ("cloud", _) => true,
43            ("official" | "trial", false) => true,
44            _ => false,
45        }
46    }
47    pub fn assert_enterprise_edition(&self) -> RawResult<()> {
48        match (self.edition.as_str(), self.expired) {
49            ("cloud", _) => Ok(()),
50            ("official" | "trial", false) => Ok(()),
51            ("official" | "trial", true) => {
52                Err(RawError::from_string("your edition is expired".to_string()))
53            }
54            _ => Err(RawError::from_string(format!(
55                "edition: {}; expired: {}",
56                self.edition, self.expired
57            ))),
58        }
59    }
60}
61
62pub trait InlinableWrite: Write {
63    #[inline]
64    /// Write `usize` length as little endian `N` bytes.
65    fn write_len_with_width<const N: usize>(&mut self, len: usize) -> std::io::Result<usize> {
66        self.write_all(&len.to_le_bytes()[0..N])?;
67        Ok(N)
68    }
69
70    #[inline]
71    /// Write a [u8] value to writer.
72    fn write_u8_le(&mut self, value: u8) -> std::io::Result<usize> {
73        self.write(&[value])
74    }
75
76    #[inline]
77    /// Write a [u16] value to writer.
78    fn write_u16_le(&mut self, value: u16) -> std::io::Result<usize> {
79        self.write(&value.to_le_bytes())
80    }
81
82    #[inline]
83    /// Write a [u32] value to writer.
84    fn write_u32_le(&mut self, value: u32) -> std::io::Result<usize> {
85        self.write(&value.to_le_bytes())
86    }
87
88    #[inline]
89    /// Write a [i64] value to writer.
90    fn write_i64_le(&mut self, value: i64) -> std::io::Result<usize> {
91        self.write(&value.to_le_bytes())
92    }
93
94    #[inline]
95    /// Write a [u64] value to writer.
96    fn write_u64_le(&mut self, value: u64) -> std::io::Result<usize> {
97        self.write(&value.to_le_bytes())
98    }
99
100    #[inline]
101    /// Write a [u128] value to writer.
102    fn write_u128_le(&mut self, value: u128) -> std::io::Result<usize> {
103        self.write(&value.to_le_bytes())
104    }
105
106    #[inline]
107    /// Write inlined bytes to writer with specific length width `N`.
108    ///
109    /// The inlined bytes are constructed as:
110    ///
111    /// ```text
112    /// +--------------+-----------------+
113    /// | len: N bytes | data: len bytes |
114    /// +--------------+-----------------+
115    /// ```
116    ///
117    ///  ## Safety
118    ///
119    ///  Write inlined bytes may not be safe if the input bytes length overflows to the width.
120    ///  For example, write `256` bytes with length width `1` is not safe.
121    fn write_inlined_bytes<const N: usize>(&mut self, bytes: &[u8]) -> std::io::Result<usize> {
122        debug_assert_eq!(bytes.len() >> (N * 8), 0);
123        let l = self.write(&bytes.len().to_le_bytes()[0..N])?;
124        self.write_all(bytes)?;
125        Ok(l + bytes.len())
126    }
127
128    #[inline]
129    /// Write inlined string with specific length width `N`.
130    fn write_inlined_str<const N: usize>(&mut self, s: &str) -> std::io::Result<usize> {
131        self.write_inlined_bytes::<N>(s.as_bytes())
132    }
133
134    #[inline]
135    /// Write an inlinable object.
136    fn write_inlinable<T: Inlinable>(&mut self, value: &T) -> std::io::Result<usize>
137    where
138        Self: Sized,
139    {
140        value.write_inlined(self)
141    }
142}
143
144impl<T> InlinableWrite for T where T: Write {}
145impl<T> InlinableRead for T where T: Read {}
146
147macro_rules! _impl_read_exact {
148    ($ty: ty, $N: literal) => {
149        paste::paste! {
150            fn [<read_ $ty>](&mut self) -> std::io::Result<$ty> {
151                let mut bytes = [0; $N];
152                self.read_exact(&mut bytes)?;
153                Ok($ty::from_le_bytes(bytes))
154            }
155        }
156    };
157}
158pub trait InlinableRead: Read {
159    #[inline]
160    /// Read `N` bytes as `usize`.
161    ///
162    /// Only 1/2/4/8 is valid as `N`.
163    fn read_len_with_width<const N: usize>(&mut self) -> std::io::Result<usize> {
164        let mut bytes: [u8; N] = [0; N];
165        self.read_exact(&mut bytes)?;
166        let len = match N {
167            1 => bytes[0] as usize,
168            2 => unsafe { *std::mem::transmute::<*const u8, *const u16>(bytes.as_ptr()) as usize },
169            4 => unsafe { *std::mem::transmute::<*const u8, *const u32>(bytes.as_ptr()) as usize },
170            8 => unsafe { *std::mem::transmute::<*const u8, *const u64>(bytes.as_ptr()) as usize },
171            _ => unreachable!(),
172        };
173        Ok(len)
174    }
175
176    fn read_f32(&mut self) -> std::io::Result<f32> {
177        let mut bytes = [0; 4];
178        self.read_exact(&mut bytes)?;
179        Ok(f32::from_le_bytes(bytes))
180    }
181
182    fn read_f64(&mut self) -> std::io::Result<f64> {
183        let mut bytes = [0; 8];
184        self.read_exact(&mut bytes)?;
185        Ok(f64::from_le_bytes(bytes))
186    }
187
188    fn read_u8(&mut self) -> std::io::Result<u8> {
189        let mut bytes = [0; 1];
190        self.read_exact(&mut bytes)?;
191        Ok(u8::from_le_bytes(bytes))
192    }
193    fn read_u16(&mut self) -> std::io::Result<u16> {
194        let mut bytes = [0; 2];
195        self.read_exact(&mut bytes)?;
196        Ok(u16::from_le_bytes(bytes))
197    }
198
199    fn read_u32(&mut self) -> std::io::Result<u32> {
200        let mut bytes = [0; 4];
201        self.read_exact(&mut bytes)?;
202        Ok(u32::from_le_bytes(bytes))
203    }
204
205    fn read_u64(&mut self) -> std::io::Result<u64> {
206        let mut bytes = [0; 8];
207        self.read_exact(&mut bytes)?;
208        Ok(u64::from_le_bytes(bytes))
209    }
210
211    fn read_u128(&mut self) -> std::io::Result<u128> {
212        let mut bytes = [0; 16];
213        self.read_exact(&mut bytes)?;
214        Ok(u128::from_le_bytes(bytes))
215    }
216
217    #[inline]
218    /// Read a bytes `len` with width `N` and the next `len - N` bytes into a `Vec`。
219    ///
220    /// The bytes contains:
221    ///
222    /// ```text
223    /// +--------------+-----------------+
224    /// | len: N bytes | data: len - N bytes |
225    /// +--------------+-----------------+
226    /// ```
227    ///
228    fn read_len_with_data<const N: usize>(&mut self) -> std::io::Result<Vec<u8>> {
229        let len = self.read_len_with_width::<N>()?;
230        let mut buf = Vec::with_capacity(len);
231        buf.extend(&(len as u64).to_le_bytes()[0..N]);
232        buf.resize(len, 0);
233        self.read_exact(&mut buf[N..])?;
234        Ok(buf)
235    }
236    #[inline]
237    /// Read inlined bytes with specific length width `N`.
238    ///
239    /// The inlined bytes are constructed as:
240    ///
241    /// ```text
242    /// +--------------+-----------------+
243    /// | len: N bytes | data: len bytes |
244    /// +--------------+-----------------+
245    /// ```
246    ///
247    fn read_inlined_bytes<const N: usize>(&mut self) -> std::io::Result<Vec<u8>> {
248        let len = self.read_len_with_width::<N>()?;
249        let mut buf = vec![0; len];
250        self.read_exact(&mut buf)?;
251        Ok(buf)
252    }
253
254    #[inline]
255    /// Read inlined string with specific length width `N`.
256    ///
257    /// The inlined string are constructed as:
258    ///
259    /// ```text
260    /// +--------------+-----------------+
261    /// | len: N bytes | data: len bytes |
262    /// +--------------+-----------------+
263    /// ```
264    ///
265    fn read_inlined_str<const N: usize>(&mut self) -> std::io::Result<String> {
266        self.read_inlined_bytes::<N>().and_then(|vec| {
267            String::from_utf8(vec)
268                .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
269        })
270    }
271
272    #[inline]
273    /// Read some bytes into inlinable object.
274    fn read_inlinable<T: Inlinable>(&mut self) -> std::io::Result<T>
275    where
276        Self: Sized,
277    {
278        T::read_inlined(self)
279    }
280}
281
282pub struct InlineOpts {
283    pub opts: BTreeMap<String, String>,
284}
285
286/// If one struct could be serialized/flattened to bytes array, we call it **inlinable**.
287pub trait Inlinable {
288    /// Read inlined bytes into object.
289    fn read_inlined<R: Read>(reader: &mut R) -> std::io::Result<Self>
290    where
291        Self: Sized;
292
293    fn read_optional_inlined<R: Read>(reader: &mut R) -> std::io::Result<Option<Self>>
294    where
295        Self: Sized,
296    {
297        Self::read_inlined(reader).map(Some)
298    }
299
300    /// Write inlined bytes to a writer.
301    fn write_inlined<W: Write>(&self, wtr: &mut W) -> std::io::Result<usize>;
302
303    /// Write inlined bytes with specific options
304    fn write_inlined_with<W: Write>(
305        &self,
306        wtr: &mut W,
307        _opts: InlineOpts,
308    ) -> std::io::Result<usize> {
309        self.write_inlined(wtr)
310    }
311
312    #[inline]
313    /// Get inlined bytes as vector.
314    fn inlined(&self) -> Vec<u8> {
315        let mut buf = Vec::new();
316        self.write_inlined(&mut buf)
317            .expect("write to vec should always be success");
318        buf
319    }
320
321    #[inline]
322    /// Get inlined bytes as printable string, all the bytes will displayed with escaped ascii code.
323    fn printable_inlined(&self) -> String {
324        self.inlined().escape_ascii().to_string()
325    }
326}
327
328/// If one struct could be serialized/flattened to bytes array, we call it **inlinable**.
329#[async_trait::async_trait]
330pub trait AsyncInlinable {
331    /// Read inlined bytes into object.
332    async fn read_inlined<R: AsyncRead + Send + Unpin>(reader: &mut R) -> std::io::Result<Self>
333    where
334        Self: Sized;
335
336    async fn read_optional_inlined<R: AsyncRead + Send + Unpin>(
337        reader: &mut R,
338    ) -> std::io::Result<Option<Self>>
339    where
340        Self: Sized,
341    {
342        Self::read_inlined(reader).await.map(Some)
343    }
344
345    /// Write inlined bytes to a writer.
346    async fn write_inlined<W: AsyncWrite + Send + Unpin>(
347        &self,
348        wtr: &mut W,
349    ) -> std::io::Result<usize>;
350
351    /// Write inlined bytes with specific options
352    async fn write_inlined_with<W: AsyncWrite + Send + Unpin>(
353        &self,
354        wtr: &mut W,
355        _opts: InlineOpts,
356    ) -> std::io::Result<usize> {
357        self.write_inlined(wtr).await
358    }
359
360    #[inline]
361    /// Get inlined bytes as vector.
362    async fn inlined(&self) -> Vec<u8> {
363        let mut buf = Vec::new();
364        self.write_inlined(&mut buf)
365            .await
366            .expect("write to vec should always be success");
367        buf
368    }
369
370    #[inline]
371    /// Get inlined bytes as printable string, all the bytes will displayed with escaped ascii code.
372    async fn printable_inlined(&self) -> String {
373        self.inlined().await.escape_ascii().to_string()
374    }
375}
376
377#[test]
378fn inlined_bytes() -> std::io::Result<()> {
379    let s = "abcd";
380    let mut vec: Vec<u8> = Vec::new();
381    let bytes = InlinableWrite::write_inlined_bytes::<1>(&mut vec, s.as_bytes())?;
382    assert_eq!(bytes, 5);
383    assert_eq!(&vec, b"\x04abcd");
384
385    let r = InlinableRead::read_inlined_str::<1>(&mut vec.as_slice())?;
386    assert_eq!(r, "abcd");
387    Ok(())
388}