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 into_shared(self) -> Shared {
86        self.into_bytes()
87    }
88
89    pub(crate) fn into_owned(self) -> Vec<u8> {
90        match self {
91            Self::Owned(buf) => buf,
92            Self::Shared(buf) => buf.as_ref().to_vec(),
93            Self::Borrowed(buf) => buf.as_slice().to_vec(),
94            Self::Retained(buf) => buf.as_slice().to_vec(),
95            Self::StaticSlice(buf) => buf.to_vec(),
96        }
97    }
98
99    pub(crate) fn as_owned_mut(&mut self) -> &mut Vec<u8> {
100        if matches!(
101            self,
102            Self::Shared(_) | Self::Borrowed(_) | Self::Retained(_) | Self::StaticSlice(_)
103        ) {
104            let old = std::mem::replace(self, Self::empty());
105            *self = Self::Owned(old.into_owned());
106        }
107        match self {
108            Self::Owned(buf) => buf,
109            _ => unreachable!("response body must be owned after conversion"),
110        }
111    }
112}
113
114impl<'req> From<Owned> for Body<'req> {
115    fn from(body: Owned) -> Self {
116        Self::Shared(body.freeze())
117    }
118}
119
120impl<'req> From<Shared> for Body<'req> {
121    fn from(body: Shared) -> Self {
122        Self::Shared(body)
123    }
124}
125
126impl<'req> From<Bytes<Borrowed<'req>>> for Body<'req> {
127    fn from(body: Bytes<Borrowed<'req>>) -> Self {
128        Self::Borrowed(body)
129    }
130}
131
132impl<'req> From<Bytes<Retained>> for Body<'req> {
133    fn from(body: Bytes<Retained>) -> Self {
134        Self::Retained(body)
135    }
136}
137
138impl<'req> From<Vec<u8>> for Body<'req> {
139    fn from(body: Vec<u8>) -> Self {
140        Self::Owned(body)
141    }
142}
143
144impl<'req> From<String> for Body<'req> {
145    fn from(body: String) -> Self {
146        Self::Owned(body.into_bytes())
147    }
148}
149
150impl<'req> From<&[u8]> for Body<'req> {
151    fn from(body: &[u8]) -> Self {
152        Self::Owned(body.to_vec())
153    }
154}
155
156impl<'req> From<&str> for Body<'req> {
157    fn from(body: &str) -> Self {
158        Self::Owned(body.as_bytes().to_vec())
159    }
160}