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
use crate::message::utf8_b; use hyperx::{ header::{Formatter as HeaderFormatter, Header, RawLike}, Error as HeaderError, Result as HyperResult, }; use std::{fmt::Result as FmtResult, str::from_utf8}; macro_rules! text_header { ( $type_name: ident, $header_name: expr ) => { #[derive(Debug, Clone, PartialEq)] pub struct $type_name(pub String); impl Header for $type_name { fn header_name() -> &'static str { $header_name } fn parse_header<'a, T>(raw: &'a T) -> HyperResult<$type_name> where T: RawLike<'a>, Self: Sized, { raw.one() .ok_or(HeaderError::Header) .and_then(parse_text) .map($type_name) } fn fmt_header(&self, f: &mut HeaderFormatter) -> FmtResult { fmt_text(&self.0, f) } } }; } text_header!(Subject, "Subject"); text_header!(Comments, "Comments"); text_header!(Keywords, "Keywords"); text_header!(InReplyTo, "In-Reply-To"); text_header!(References, "References"); text_header!(MessageId, "Message-Id"); text_header!(UserAgent, "User-Agent"); fn parse_text(raw: &[u8]) -> HyperResult<String> { if let Ok(src) = from_utf8(raw) { if let Some(txt) = utf8_b::decode(src) { return Ok(txt); } } Err(HeaderError::Header) } fn fmt_text(s: &str, f: &mut HeaderFormatter) -> FmtResult { f.fmt_line(&utf8_b::encode(s)) } #[cfg(test)] mod test { use super::Subject; use hyperx::header::Headers; #[test] fn format_ascii() { let mut headers = Headers::new(); headers.set(Subject("Sample subject".into())); assert_eq!(format!("{}", headers), "Subject: Sample subject\r\n"); } #[test] fn format_utf8() { let mut headers = Headers::new(); headers.set(Subject("Тема сообщения".into())); assert_eq!( format!("{}", headers), "Subject: =?utf-8?b?0KLQtdC80LAg0YHQvtC+0LHRidC10L3QuNGP?=\r\n" ); } #[test] fn parse_ascii() { let mut headers = Headers::new(); headers.set_raw("Subject", "Sample subject"); assert_eq!( headers.get::<Subject>(), Some(&Subject("Sample subject".into())) ); } #[test] fn parse_utf8() { let mut headers = Headers::new(); headers.set_raw( "Subject", "=?utf-8?b?0KLQtdC80LAg0YHQvtC+0LHRidC10L3QuNGP?=", ); assert_eq!( headers.get::<Subject>(), Some(&Subject("Тема сообщения".into())) ); } }