sark_http/payload/response/headers/
mod.rs1pub mod head;
4mod list;
5mod name;
6pub mod set;
7pub mod value;
8
9pub use list::List;
10pub use name::Name;
11
12use crate::field;
13
14#[derive(Clone, Copy, Debug, PartialEq, Eq)]
15pub enum Error {
16 Managed,
17 Syntax(field::Error),
18}
19
20#[derive(Clone, Copy, Debug, PartialEq, Eq)]
22#[repr(transparent)]
23pub struct Entry<'a>(field::Entry<'a>);
24
25#[derive(Clone, Copy, Debug, PartialEq, Eq)]
27#[repr(transparent)]
28pub struct Group<'a>(field::Group<'a>);
29
30impl<'a> Group<'a> {
31 pub const fn try_new(group: field::Group<'a>) -> Result<Self, Error> {
32 let entries = group.entries();
33 let mut index = 0;
34 while index < entries.len() {
35 if let Err(error) = Name::try_bytes(entries[index].name()) {
36 return Err(error);
37 }
38 index += 1;
39 }
40 Ok(Self(group))
41 }
42
43 pub const fn as_fields(&self) -> &field::Group<'a> {
44 &self.0
45 }
46}
47
48impl<'a> Entry<'a> {
49 pub const fn new(name: Name<&'a [u8]>, value: field::Value<&'a [u8]>) -> Self {
50 Self(field::Entry::new(name.0, value))
51 }
52
53 pub const fn with_index(self, indexing: field::Indexing) -> Self {
54 Self(self.0.with_index(indexing))
55 }
56
57 pub const fn name(self) -> &'a [u8] {
58 self.0.name()
59 }
60
61 pub const fn value(self) -> field::Value<&'a [u8]> {
62 self.0.value()
63 }
64
65 pub const fn indexing(self) -> field::Indexing {
66 self.0.indexing()
67 }
68
69 pub const fn as_field(&self) -> field::Entry<'a> {
70 self.0
71 }
72}
73
74pub trait Sink<'field> {
76 fn entry(&mut self, field: Entry<'field>);
77
78 fn group(&mut self, group: &Group<'field>) {
80 for entry in group.0.entries() {
81 self.entry(Entry(*entry));
82 }
83 }
84
85 fn field(&mut self, name: Name<&'field [u8]>, value: field::Value<&'field [u8]>) {
86 self.entry(Entry::new(name, value));
87 }
88
89 fn encoded_with<E: field::Encode>(
90 &mut self,
91 name: Name<&'field [u8]>,
92 value: E,
93 indexing: field::Indexing,
94 );
95
96 fn generated<E: field::Encode>(&mut self, name: Name<&'field [u8]>, value: E) {
97 self.encoded_with(name, value, field::Indexing::Allowed);
98 }
99}
100
101pub trait Source {
103 fn emit<'field>(&'field self, sink: &mut impl Sink<'field>);
104}
105
106#[repr(transparent)]
108pub struct Fields<S>(S);
109
110impl<S: Source> Fields<S> {
111 pub const fn new(source: S) -> Self {
112 Self(source)
113 }
114}
115
116struct Adapter<'a, S>(&'a mut S);
117
118impl<S: Source> field::Source for Fields<S> {
119 fn emit<'field>(&'field self, sink: &mut impl field::Sink<'field>) {
120 self.0.emit(&mut Adapter(sink));
121 }
122}
123
124impl<'field, S: field::Sink<'field>> Sink<'field> for Adapter<'_, S> {
125 fn entry(&mut self, field: Entry<'field>) {
126 self.0.entry(field.0);
127 }
128
129 fn group(&mut self, group: &Group<'field>) {
130 self.0.group(group.as_fields());
131 }
132
133 fn encoded_with<E: field::Encode>(
134 &mut self,
135 name: Name<&'field [u8]>,
136 value: E,
137 indexing: field::Indexing,
138 ) {
139 self.0.encoded_with(name.0, value, indexing);
140 }
141}
142
143impl Source for () {
144 fn emit<'field>(&'field self, sink: &mut impl Sink<'field>) {
145 let fields: &[Entry<'_>] = &[];
146 fields.emit(sink);
147 }
148}
149
150impl Source for Group<'_> {
151 fn emit<'field>(&'field self, sink: &mut impl Sink<'field>) {
152 sink.group(self);
153 }
154}
155
156impl<S: Source + ?Sized> Source for &S {
157 fn emit<'field>(&'field self, sink: &mut impl Sink<'field>) {
158 (**self).emit(sink);
159 }
160}
161
162impl Source for [Entry<'_>] {
163 fn emit<'field>(&'field self, sink: &mut impl Sink<'field>) {
164 for entry in self {
165 sink.entry(*entry);
166 }
167 }
168}
169
170impl<const N: usize> Source for [Entry<'_>; N] {
171 fn emit<'field>(&'field self, sink: &mut impl Sink<'field>) {
172 self.as_slice().emit(sink);
173 }
174}
175
176impl Source for Vec<Entry<'_>> {
177 fn emit<'field>(&'field self, sink: &mut impl Sink<'field>) {
178 self.as_slice().emit(sink);
179 }
180}