Skip to main content

sark_core/http/response/
body.rs

1use o3::buffer::{Borrowed, Bytes, Owned, Retained, Shared};
2
3#[derive(Clone)]
4pub enum Body<'req> {
5    Owned(Vec<u8>),
6    Shared(Shared),
7    Borrowed(Bytes<Borrowed<'req>>),
8    Retained(Bytes<Retained>),
9    StaticSlice(&'static [u8]),
10}
11
12impl<'req> std::fmt::Debug for Body<'req> {
13    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14        match self {
15            Self::Owned(buf) => f
16                .debug_struct("Body::Owned")
17                .field("len", &buf.len())
18                .finish(),
19            Self::Shared(buf) => f
20                .debug_struct("Body::Shared")
21                .field("len", &buf.len())
22                .finish(),
23            Self::Borrowed(buf) => f
24                .debug_struct("Body::Borrowed")
25                .field("len", &buf.len())
26                .finish(),
27            Self::Retained(buf) => f
28                .debug_struct("Body::Retained")
29                .field("len", &buf.len())
30                .finish(),
31            Self::StaticSlice(buf) => f
32                .debug_struct("Body::StaticSlice")
33                .field("len", &buf.len())
34                .finish(),
35        }
36    }
37}
38
39impl<'req> Body<'req> {
40    pub(crate) fn empty() -> Self {
41        Self::Owned(Vec::new())
42    }
43
44    pub(crate) fn len(&self) -> usize {
45        match self {
46            Self::Owned(buf) => buf.len(),
47            Self::Shared(buf) => buf.len(),
48            Self::Borrowed(buf) => buf.len(),
49            Self::Retained(buf) => buf.len(),
50            Self::StaticSlice(buf) => buf.len(),
51        }
52    }
53
54    pub fn as_bytes(&self) -> &[u8] {
55        match self {
56            Self::Owned(buf) => buf.as_ref(),
57            Self::Shared(buf) => buf.as_ref(),
58            Self::Borrowed(buf) => buf.as_slice(),
59            Self::Retained(buf) => buf.as_slice(),
60            Self::StaticSlice(buf) => buf,
61        }
62    }
63
64    pub(crate) fn is_shared(&self) -> bool {
65        matches!(
66            self,
67            Self::Shared(_) | Self::Borrowed(_) | Self::Retained(_) | Self::StaticSlice(_)
68        )
69    }
70
71    pub(crate) fn into_bytes(self) -> Shared {
72        match self {
73            Self::Owned(buf) => Shared::from(buf),
74            Self::Shared(buf) => buf,
75            Self::Borrowed(buf) => Shared::copy_from_slice(buf.as_slice()),
76            Self::Retained(buf) => buf.into_shared(),
77            Self::StaticSlice(buf) => Shared::from_static(buf),
78        }
79    }
80
81    pub(crate) fn body_len(&self) -> usize {
82        self.len()
83    }
84
85    pub(crate) fn write_to(&self, out: &mut [u8]) -> usize {
86        let body = self.as_bytes();
87        out[..body.len()].copy_from_slice(body);
88        body.len()
89    }
90
91    pub(crate) fn into_shared(self) -> Shared {
92        self.into_bytes()
93    }
94
95    pub(crate) fn into_owned(self) -> Vec<u8> {
96        match self {
97            Self::Owned(buf) => buf,
98            Self::Shared(buf) => buf.as_ref().to_vec(),
99            Self::Borrowed(buf) => buf.as_slice().to_vec(),
100            Self::Retained(buf) => buf.as_slice().to_vec(),
101            Self::StaticSlice(buf) => buf.to_vec(),
102        }
103    }
104
105    pub(crate) fn as_owned_mut(&mut self) -> &mut Vec<u8> {
106        if matches!(
107            self,
108            Self::Shared(_) | Self::Borrowed(_) | Self::Retained(_) | Self::StaticSlice(_)
109        ) {
110            let old = std::mem::replace(self, Self::empty());
111            *self = Self::Owned(old.into_owned());
112        }
113        match self {
114            Self::Owned(buf) => buf,
115            _ => unreachable!("response body must be owned after conversion"),
116        }
117    }
118}
119
120impl<'req> From<Owned> for Body<'req> {
121    fn from(body: Owned) -> Self {
122        Self::Shared(body.freeze())
123    }
124}
125
126impl<'req> From<Shared> for Body<'req> {
127    fn from(body: Shared) -> Self {
128        Self::Shared(body)
129    }
130}
131
132impl<'req> From<Bytes<Borrowed<'req>>> for Body<'req> {
133    fn from(body: Bytes<Borrowed<'req>>) -> Self {
134        Self::Borrowed(body)
135    }
136}
137
138impl<'req> From<Bytes<Retained>> for Body<'req> {
139    fn from(body: Bytes<Retained>) -> Self {
140        Self::Retained(body)
141    }
142}
143
144impl<'req> From<Vec<u8>> for Body<'req> {
145    fn from(body: Vec<u8>) -> Self {
146        Self::Owned(body)
147    }
148}
149
150impl<'req> From<String> for Body<'req> {
151    fn from(body: String) -> Self {
152        Self::Owned(body.into_bytes())
153    }
154}
155
156impl<'req> From<&[u8]> for Body<'req> {
157    fn from(body: &[u8]) -> Self {
158        Self::Owned(body.to_vec())
159    }
160}
161
162impl<'req> From<&str> for Body<'req> {
163    fn from(body: &str) -> Self {
164        Self::Owned(body.as_bytes().to_vec())
165    }
166}