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
use crate::cookie; use crate::http::{header, HeaderValue, Response}; use cookie::Cookie; use derive_more::{Display, From}; use std::collections::HashMap; #[derive(Debug, Display, From)] pub enum ResponseError { #[display(fmt = "header value (`{:?}`) is not string: {}", value, msg)] HeaderValueNotStr { value: HeaderValue, msg: header::ToStrError, }, #[display(fmt = "parse cookie('{}') error: {}", value, msg)] ParseCookieError { value: String, msg: cookie::ParseError, }, } pub trait ResponseExt { fn cookies(&self) -> Result<Vec<Cookie>, ResponseError>; fn cookie_map(&self) -> Result<HashMap<String, Vec<Cookie>>, ResponseError>; } impl<T> ResponseExt for Response<T> { fn cookies(&self) -> Result<Vec<Cookie>, ResponseError> { let mut cookies = Vec::new(); for cookie in self.headers().get_all(header::SET_COOKIE) { let cookie_str = cookie.to_str().map_err(|err| (cookie.clone(), err))?; cookies.push(Cookie::parse(cookie_str).map_err(|err| (cookie_str.to_owned(), err))?) } Ok(cookies) } fn cookie_map(&self) -> Result<HashMap<String, Vec<Cookie>>, ResponseError> { let mut map = HashMap::new(); for cookie in self.headers().get_all(header::SET_COOKIE) { let cookie_str = cookie.to_str().map_err(|err| (cookie.clone(), err))?; let cookie = Cookie::parse(cookie_str).map_err(|err| (cookie_str.to_owned(), err))?; match map.get_mut(cookie.name()) { None => { map.insert(cookie.name().to_owned(), vec![cookie]); } Some(list) => list.push(cookie), } } Ok(map) } }