1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
use std::fmt; use std::io::{Error, ErrorKind}; use std::iter::Iterator; #[derive(Default, Clone)] pub struct Headers { f: Vec<(Vec<u8>, Vec<u8>)>, } impl Headers { pub fn new() -> Self { Self::default() } pub fn ok() -> Self { Self { f: vec![(":status".into(), "200".into())], } } pub fn ok_proto() -> Self { Self { f: vec![ (":status".into(), "200".into()), ("content-type".into(), "application/protobuf".into()), ], } } pub fn with_error<P: Into<Vec<u8>>>(status: u32, p: P) -> Self { Self { f: vec![ (":status".into(), format!("{}", status).as_bytes().to_vec()), (":error".into(), p.into()), ], } } pub fn with_path<P: Into<Vec<u8>>>(p: P) -> Self { Self { f: vec![(":path".into(), p.into())], } } pub fn with<K: Into<Vec<u8>>, V: Into<Vec<u8>>>(k: K, v: V) -> Self { Self { f: vec![(k.into(), v.into())], } } pub fn get(&self, key: &[u8]) -> Option<&[u8]> { let mut val = None; for header in &self.f { if header.0 == key { val = Some(header.1.as_slice()); } } val } pub fn path(&self) -> Option<&[u8]> { let mut path = None; for header in &self.f { if header.0 == b":path" { path = Some(header.1.as_slice()); } } path } pub fn add(&mut self, k: Vec<u8>, v: Vec<u8>) { self.f.push((k, v)); } pub fn and(mut self, k: Vec<u8>, v: Vec<u8>) -> Self { self.f.push((k, v)); self } pub fn encode(&self) -> Vec<u8> { use hpack::Encoder; let m = self.f.iter().map(|v| (v.0.as_slice(), v.1.as_slice())); Encoder::new().encode(m) } pub fn decode(b: &[u8]) -> Result<Self, Error> { use hpack::Decoder; let h = Decoder::new() .decode(&b) .map_err(|e| Error::new(ErrorKind::InvalidData, format!("{:?}", e)))?; Ok(Self { f: h }) } pub fn iter<'a>(&'a self) -> impl Iterator<Item = (&[u8], &[u8])> + 'a { self.f.iter().map(|v| (v.0.as_slice(), v.1.as_slice())) } } impl fmt::Debug for Headers { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "[")?; for (k, v) in &self.f { write!(f, "{} = {}, ", String::from_utf8_lossy(&k), String::from_utf8_lossy(&v))?; } write!(f, "]")?; Ok(()) } }