imap_proto/parser/
bodystructure.rs1use std::collections::HashMap;
2
3use crate::types::BodyStructure;
4pub struct BodyStructParser<'a> {
7 root: &'a BodyStructure<'a>,
8 prefix: Vec<u32>,
9 iter: u32,
10 map: HashMap<Vec<u32>, &'a BodyStructure<'a>>,
11}
12
13impl<'a> BodyStructParser<'a> {
14 pub fn new(root: &'a BodyStructure<'a>) -> Self {
20 let mut parser = BodyStructParser {
21 root,
22 prefix: vec![],
23 iter: 1,
24 map: HashMap::new(),
25 };
26
27 parser.parse(parser.root);
28 parser
29 }
30
31 pub fn search<F>(&self, func: F) -> Option<Vec<u32>>
37 where
38 F: Fn(&'a BodyStructure<'a>) -> bool,
39 {
40 let elem: Vec<_> = self
41 .map
42 .iter()
43 .filter_map(|(k, v)| {
44 if func(v) {
45 let slice: &[u32] = k;
46 Some(slice)
47 } else {
48 None
49 }
50 })
51 .collect();
52 elem.first().map(|a| a.to_vec())
53 }
54
55 fn parse(&mut self, node: &'a BodyStructure) {
57 match node {
58 BodyStructure::Multipart { bodies, .. } => {
59 let vec = self.prefix.clone();
60 self.map.insert(vec, node);
61
62 for (i, n) in bodies.iter().enumerate() {
63 self.iter += i as u32;
64 self.prefix.push(self.iter);
65 self.parse(n);
66 self.prefix.pop();
67 }
68 self.iter = 1;
69 }
70 _ => {
71 let vec = self.prefix.clone();
72 self.map.insert(vec, node);
73 }
74 };
75 }
76}