manas_http/representation/impl_/common/data/
bytes_inmem.rs

1//! I define type to represent in-memory bytes data.
2//!
3
4use std::io::{Read, Write};
5
6use bytes::Bytes;
7use ecow::{eco_vec, EcoVec};
8
9/// Bytes inmem data.
10#[derive(Debug, Clone, Default)]
11pub struct BytesInmem {
12    /// Inmem bytes.
13    pub(super) bytes: EcoVec<Bytes>,
14
15    /// Cached size of the bytes.
16    pub(super) size: u64,
17}
18
19impl From<EcoVec<Bytes>> for BytesInmem {
20    #[inline]
21    fn from(bytes: EcoVec<Bytes>) -> Self {
22        Self {
23            size: bytes.iter().fold(0, |acc, e| acc + e.len() as u64),
24            bytes,
25        }
26    }
27}
28
29impl From<Bytes> for BytesInmem {
30    #[inline]
31    fn from(bytes: Bytes) -> Self {
32        Self {
33            size: bytes.len() as u64,
34            bytes: eco_vec![bytes],
35        }
36    }
37}
38
39impl From<String> for BytesInmem {
40    #[inline]
41    fn from(v: String) -> Self {
42        let bytes: Bytes = v.into();
43        Self {
44            size: bytes.len() as u64,
45            bytes: eco_vec![bytes],
46        }
47    }
48}
49
50impl From<BytesInmem> for EcoVec<Bytes> {
51    fn from(value: BytesInmem) -> Self {
52        value.bytes
53    }
54}
55
56impl BytesInmem {
57    /// Get bytes.
58    #[inline]
59    pub fn bytes(&self) -> &EcoVec<Bytes> {
60        &self.bytes
61    }
62
63    /// Get size of the bytes data.
64    #[inline]
65    pub fn size(&self) -> u64 {
66        self.size
67    }
68
69    /// Get as reader.
70    #[inline]
71    pub fn as_read(&self) -> BytesInmemReader {
72        BytesInmemReader::new(self.bytes.clone())
73    }
74}
75
76/// A reader over slice of bytes chunks.
77#[derive(Debug, Clone)]
78pub struct BytesInmemReader {
79    data: EcoVec<Bytes>,
80    pos: usize,
81}
82
83impl BytesInmemReader {
84    /// Create a new [`BytesInmemReader`].
85    pub fn new(data: EcoVec<Bytes>) -> Self {
86        Self { data, pos: 0 }
87    }
88}
89
90impl Read for BytesInmemReader {
91    fn read(&mut self, mut buf: &mut [u8]) -> std::io::Result<usize> {
92        if let Some(chunk) = self.data.get(self.pos) {
93            buf.write_all(chunk)?;
94            self.pos += 1;
95            Ok(chunk.len())
96        } else {
97            Ok(0)
98        }
99    }
100}