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 crate::body::Body; use crate::fragment::Fragment; use crate::trailer::Trailer; use std::convert::TryFrom; #[derive(Debug, PartialEq, Clone)] pub struct Bodies { bodies: Vec<Body>, } impl From<Vec<Body>> for Bodies { fn from(bodies: Vec<Body>) -> Self { Bodies { bodies } } } impl From<Bodies> for String { fn from(bodies: Bodies) -> Self { bodies .bodies .into_iter() .map(String::from) .collect::<Vec<_>>() .join("\n\n") } } impl From<Vec<Fragment>> for Bodies { fn from(bodies: Vec<Fragment>) -> Self { let raw_body = bodies .iter() .filter_map(|values| { if let Fragment::Body(body) = values { Some(body.clone()) } else { None } }) .collect::<Vec<_>>(); let trailer_count = raw_body .clone() .into_iter() .rev() .take_while(|body| body.is_empty() || Trailer::try_from(body.clone()).is_ok()) .count(); let non_trailer_item_count = raw_body.len() - trailer_count; raw_body .into_iter() .enumerate() .skip(1) .take(non_trailer_item_count - 1) .map(|(_, body)| body) .collect::<Vec<Body>>() .into() } } #[cfg(test)] mod tests { use super::Bodies; use crate::body::Body; use crate::fragment::Fragment; use indoc::indoc; use pretty_assertions::assert_eq; #[test] fn it_can_give_me_it_as_a_string() { let bodies = Bodies::from(vec![ Body::from("Message Body"), Body::from("Another Message Body"), ]); assert_eq!( String::from(bodies), String::from(indoc!( " Message Body Another Message Body" )) ) } #[test] fn it_can_parse_itself_from_an_ast() { let bodies = Bodies::from(vec![ Fragment::Body(Body::from("Subject Line")), Fragment::Body(Body::default()), Fragment::Body(Body::from("Some content in the body of the message")), Fragment::Body(Body::default()), Fragment::Body(Body::from(indoc!( " Co-authored-by: Billie Thomposon <billie@example.com> Co-authored-by: Someone Else <someone@example.com> " ))), ]); assert_eq!( bodies, Bodies::from(vec![ Body::default(), Body::from("Some content in the body of the message"), ]) ) } }