typed_headers/impls/
content_length.rs1use http::header::{self, HeaderName, HeaderValue, CONTENT_LENGTH};
2use std::ops::{Deref, DerefMut};
3
4use crate::{util, Error, Header, ToValues};
5
6#[derive(Clone, Debug, PartialEq)]
28pub struct ContentLength(pub u64);
29
30impl Deref for ContentLength {
31 type Target = u64;
32
33 #[inline]
34 fn deref(&self) -> &u64 {
35 &self.0
36 }
37}
38
39impl DerefMut for ContentLength {
40 #[inline]
41 fn deref_mut(&mut self) -> &mut u64 {
42 &mut self.0
43 }
44}
45
46impl Header for ContentLength {
47 #[inline]
48 fn name() -> &'static HeaderName {
49 &CONTENT_LENGTH
50 }
51
52 #[inline]
56 fn from_values(
57 values: &mut header::ValueIter<HeaderValue>,
58 ) -> Result<Option<ContentLength>, Error> {
59 let mut length = None;
60
61 for value in values {
62 let value = value.to_str().map_err(|_| Error::invalid_value())?;
63 if value.trim().is_empty() {
64 return Err(Error::invalid_value());
65 }
66
67 for elem in value.split(',') {
68 let elem = elem.trim();
69 if elem.is_empty() {
70 continue;
71 }
72
73 let elem = elem.parse().map_err(|_| Error::invalid_value())?;
74 match length {
75 Some(length) if length != elem => return Err(Error::invalid_value()),
76 Some(_) => {}
77 None => length = Some(elem),
78 }
79 }
80 }
81
82 Ok(length.map(ContentLength))
83 }
84
85 #[inline]
86 fn to_values(&self, values: &mut ToValues) {
87 util::encode_single_value(&self.0, values);
88 }
89}