structured_cms/mime/
essence.rs1use super::{Head, Syntax};
4use structured_asn1::memory::{MemoryError, Work};
5
6struct Pattern<'a> {
7 media_type: &'a [u8],
8 subtype: &'a [u8],
9 matches: bool,
10}
11
12impl Pattern<'_> {
13 fn compare(remaining: &mut &[u8], matches: &mut bool, byte: u8) {
14 if !*matches {
15 return;
16 }
17 if remaining.is_empty() {
18 *matches = false;
19 return;
20 }
21 if !remaining[0].eq_ignore_ascii_case(&byte) {
22 *matches = false;
23 }
24 *remaining = &remaining[1..];
25 }
26}
27
28impl<const N: usize> Head for [Pattern<'_>; N] {
29 fn cost(&self) -> Result<u64, MemoryError> {
30 u64::try_from(N)
31 .ok()
32 .and_then(|count| count.checked_mul(2))
33 .ok_or(MemoryError::WorkExceeded)
34 }
35 fn type_byte(&mut self, byte: u8) {
36 for pattern in self {
37 Pattern::compare(&mut pattern.media_type, &mut pattern.matches, byte);
38 }
39 }
40 fn subtype_byte(&mut self, byte: u8) {
41 for pattern in self {
42 Pattern::compare(&mut pattern.subtype, &mut pattern.matches, byte);
43 }
44 }
45}
46
47pub struct Essences<'a, const N: usize, const XML_NORMALIZED: bool = false> {
55 syntax: Syntax<XML_NORMALIZED>,
56 patterns: [Pattern<'a>; N],
57}
58
59impl<'a, const N: usize, const XML_NORMALIZED: bool> Essences<'a, N, XML_NORMALIZED> {
60 #[must_use]
63 pub fn new(patterns: [(&'a str, &'a str); N]) -> Self {
64 Self {
65 syntax: Syntax::new(),
66 patterns: patterns.map(|(media_type, subtype)| Pattern {
67 media_type: media_type.as_bytes(),
68 subtype: subtype.as_bytes(),
69 matches: true,
70 }),
71 }
72 }
73
74 pub fn feed<W: Work>(
77 &mut self,
78 bytes: impl AsRef<[u8]>,
79 work: &W,
80 ) -> Result<bool, MemoryError> {
81 self.syntax.scan(bytes.as_ref(), work, &mut self.patterns)
82 }
83
84 #[must_use]
86 pub fn complete(&self) -> bool {
87 self.syntax.complete()
88 }
89
90 #[must_use]
93 pub fn matches(&self, index: usize) -> Option<bool> {
94 self.patterns.get(index).map(|pattern| {
95 self.complete()
96 && pattern.matches
97 && pattern.media_type.is_empty()
98 && pattern.subtype.is_empty()
99 })
100 }
101}