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 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 fn write_u8_le(&mut self, value: u8) -> std::io::Result<usize> {
73 self.write(&[value])
74 }
75
76 #[inline]
77 fn write_u16_le(&mut self, value: u16) -> std::io::Result<usize> {
79 self.write(&value.to_le_bytes())
80 }
81
82 #[inline]
83 fn write_u32_le(&mut self, value: u32) -> std::io::Result<usize> {
85 self.write(&value.to_le_bytes())
86 }
87
88 #[inline]
89 fn write_i64_le(&mut self, value: i64) -> std::io::Result<usize> {
91 self.write(&value.to_le_bytes())
92 }
93
94 #[inline]
95 fn write_u64_le(&mut self, value: u64) -> std::io::Result<usize> {
97 self.write(&value.to_le_bytes())
98 }
99
100 #[inline]
101 fn write_u128_le(&mut self, value: u128) -> std::io::Result<usize> {
103 self.write(&value.to_le_bytes())
104 }
105
106 #[inline]
107 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 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 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 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 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 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 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 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
286pub trait Inlinable {
288 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 fn write_inlined<W: Write>(&self, wtr: &mut W) -> std::io::Result<usize>;
302
303 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 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 fn printable_inlined(&self) -> String {
324 self.inlined().escape_ascii().to_string()
325 }
326}
327
328#[async_trait::async_trait]
330pub trait AsyncInlinable {
331 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 async fn write_inlined<W: AsyncWrite + Send + Unpin>(
347 &self,
348 wtr: &mut W,
349 ) -> std::io::Result<usize>;
350
351 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 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 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}