sark_http/payload/response/headers/
name.rs1use std::borrow::Cow;
2
3use crate::{
4 field::{self, storage},
5 payload::response::headers::Error,
6};
7
8#[derive(Copy, Debug, PartialEq, Eq)]
10#[repr(transparent)]
11pub struct Name<T>(pub(in crate::payload::response::headers) field::Lower<T>);
12
13impl<T: Copy> Clone for Name<T> {
14 fn clone(&self) -> Self {
15 *self
16 }
17}
18
19impl<T: storage::Bytes> Name<T> {
20 pub fn new(name: field::Lower<T>) -> Result<Self, Error> {
21 if Name::<&[u8]>::is_managed(name.as_bytes()) {
22 return Err(Error::Managed);
23 }
24 Ok(Self(name))
25 }
26
27 pub fn borrow(&self) -> Name<&[u8]> {
28 Name(self.0.borrow())
29 }
30
31 pub fn as_bytes(&self) -> &[u8] {
32 self.0.as_bytes()
33 }
34}
35
36impl<T: storage::Bytes> AsRef<[u8]> for Name<T> {
37 fn as_ref(&self) -> &[u8] {
38 self.as_bytes()
39 }
40}
41
42impl<T: storage::Text> Name<T> {
43 pub fn as_str(&self) -> &str {
44 self.0.as_str()
45 }
46}
47
48impl<T: storage::Text> AsRef<str> for Name<T> {
49 fn as_ref(&self) -> &str {
50 self.as_str()
51 }
52}
53
54impl<T> Name<T> {
55 pub fn into_inner(self) -> field::Lower<T> {
56 self.0
57 }
58}
59
60impl<'a> Name<&'a [u8]> {
61 pub const fn try_bytes(name: &'a [u8]) -> Result<Self, Error> {
62 let name = match field::Lower::try_bytes(name) {
63 Ok(name) => name,
64 Err(error) => return Err(Error::Syntax(error)),
65 };
66 if Self::is_managed(name.get()) {
67 return Err(Error::Managed);
68 }
69 Ok(Self(name))
70 }
71
72 pub const fn is_managed(name: &[u8]) -> bool {
73 name.eq_ignore_ascii_case(b"date")
74 || name.eq_ignore_ascii_case(b"server")
75 || name.eq_ignore_ascii_case(b"content-length")
76 || name.eq_ignore_ascii_case(b"connection")
77 || name.eq_ignore_ascii_case(b"transfer-encoding")
78 || name.eq_ignore_ascii_case(b"keep-alive")
79 || name.eq_ignore_ascii_case(b"proxy-connection")
80 || name.eq_ignore_ascii_case(b"upgrade")
81 || name.eq_ignore_ascii_case(b"te")
82 }
83
84 pub const fn get(self) -> &'a [u8] {
85 self.0.get()
86 }
87}
88
89impl Name<Cow<'_, str>> {
90 pub const CONTENT_TYPE: Self = Self(field::Lower::CONTENT_TYPE);
91}