Skip to main content

sark_http/field/storage/
value.rs

1use std::borrow::Cow;
2
3use o3::alloc::{self, BoxSliceExt as _};
4
5use crate::{
6    field::{Error, storage, storage::encoded},
7    h1::field,
8};
9
10/// An owned or borrowed HTTP field value validated before storage.
11#[repr(transparent)]
12#[derive(Copy, Debug, PartialEq, Eq)]
13pub struct Value<T>(pub(in crate::field) T);
14
15impl<T: Copy> Clone for Value<T> {
16    fn clone(&self) -> Self {
17        *self
18    }
19}
20
21impl<T: storage::Bytes> Value<T> {
22    pub fn new(value: T) -> Result<Self, Error> {
23        Error::value(value.as_bytes())?;
24        Ok(Self(value))
25    }
26
27    pub fn as_bytes(&self) -> &[u8] {
28        self.0.as_bytes()
29    }
30
31    pub fn borrow(&self) -> Value<&[u8]> {
32        Value(self.as_bytes())
33    }
34}
35
36impl<T> Value<T> {
37    pub fn into_inner(self) -> T {
38        self.0
39    }
40}
41
42impl<'a> Value<&'a [u8]> {
43    pub const fn try_bytes(value: &'a [u8]) -> Result<Self, Error> {
44        match Error::value(value) {
45            Ok(()) => Ok(Self(value)),
46            Err(cause) => Err(cause),
47        }
48    }
49
50    pub const fn get(self) -> &'a [u8] {
51        self.0
52    }
53}
54
55impl<'field> Value<Cow<'field, [u8]>> {
56    pub fn try_copy(value: &[u8]) -> Result<Self, storage::Error> {
57        Error::value(value).map_err(storage::Error::Syntax)?;
58        Ok(Self(Cow::Owned(
59            Box::try_copy(value)
60                .map_err(storage::Error::Allocation)?
61                .into_vec(),
62        )))
63    }
64
65    pub(crate) fn try_entry(field: field::Entry<'_>) -> Result<Self, alloc::Exhausted> {
66        Ok(Self(Cow::Owned(Box::try_copy(field.value())?.into_vec())))
67    }
68}
69
70impl Value<Cow<'_, str>> {
71    pub fn try_owned(self) -> Result<Value<String>, alloc::Exhausted> {
72        Ok(Value(storage::try_own(self.0)?))
73    }
74}
75
76impl<T: storage::Text> Value<T> {
77    pub fn as_str(&self) -> &str {
78        self.0.as_str()
79    }
80}
81
82impl<T: storage::Bytes> encoded::Encoded for Value<T> {}