cogo_http/header/common/
content_length.rs1use std::fmt;
2
3use crate::header::{HeaderFormat, Header, parsing};
4
5#[derive(Clone, Copy, Debug, PartialEq)]
33pub struct ContentLength(pub u64);
34
35impl Header for ContentLength {
36 #[inline]
37 fn header_name() -> &'static str {
38 "Content-Length"
39 }
40 fn parse_header(raw: &[Vec<u8>]) -> crate::Result<ContentLength> {
41 raw.iter()
45 .map(std::ops::Deref::deref)
46 .map(parsing::from_raw_str)
47 .fold(None, |prev, x| {
48 match (prev, x) {
49 (None, x) => Some(x),
50 (e@Some(Err(_)), _ ) => e,
51 (Some(Ok(prev)), Ok(x)) if prev == x => Some(Ok(prev)),
52 _ => Some(Err(crate::Error::Header))
53 }
54 })
55 .unwrap_or(Err(crate::Error::Header))
56 .map(ContentLength)
57 }
58}
59
60impl HeaderFormat for ContentLength {
61 #[inline]
62 fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
63 fmt::Display::fmt(&self.0, f)
64 }
65}
66
67impl fmt::Display for ContentLength {
68 #[inline]
69 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
70 fmt::Display::fmt(&self.0, f)
71 }
72}
73
74__hyper__deref!(ContentLength => u64);
75
76__hyper__tm!(ContentLength, tests {
77 test_header!(test1, vec![b"3495"], Some(HeaderField(3495)));
79
80 test_header!(test_invalid, vec![b"34v95"], None);
81
82 #[test]
84 fn test_duplicates() {
85 let parsed = HeaderField::parse_header(&[b"5"[..].into(),
86 b"5"[..].into()]).unwrap();
87 assert_eq!(parsed, HeaderField(5));
88 assert_eq!(format!("{}", parsed), "5");
89 }
90
91 test_header!(test_duplicates_vary, vec![b"5", b"6", b"5"], None);
92});
93
94bench_header!(bench, ContentLength, { vec![b"42349984".to_vec()] });