miltr_common/modifications/
recipients.rs1use std::borrow::Cow;
4
5use bytes::{BufMut, BytesMut};
6
7use crate::decoding::Parsable;
8use crate::encoding::Writable;
9use crate::{InvalidData, ProtocolError};
10use miltr_utils::ByteParsing;
11
12#[derive(Debug, Clone)]
13
14pub struct AddRecipient {
16 recipient: BytesMut,
17}
18
19impl AddRecipient {
20 const CODE: u8 = b'+';
21
22 #[must_use]
24 pub fn new(recipient: &[u8]) -> Self {
25 Self {
26 recipient: BytesMut::from_iter(recipient),
27 }
28 }
29
30 #[must_use]
32 pub fn recipient(&self) -> Cow<str> {
33 String::from_utf8_lossy(&self.recipient)
34 }
35}
36
37impl Parsable for AddRecipient {
38 const CODE: u8 = Self::CODE;
39
40 fn parse(mut buffer: BytesMut) -> Result<Self, ProtocolError> {
41 let Some(recipient) = buffer.delimited(0) else {
42 return Err(InvalidData::new(
43 "Received add recipient package without null byte terminating it",
44 buffer,
45 )
46 .into());
47 };
48
49 Ok(Self { recipient })
50 }
51}
52
53impl Writable for AddRecipient {
54 fn write(&self, buffer: &mut BytesMut) {
56 buffer.extend_from_slice(&self.recipient);
57 buffer.put_u8(0);
58 }
59
60 fn len(&self) -> usize {
61 self.recipient.len() + 1
62 }
63
64 fn code(&self) -> u8 {
65 Self::CODE
66 }
67 fn is_empty(&self) -> bool {
68 self.len() == 0
69 }
70}
71
72#[derive(Debug, Clone)]
73pub struct DeleteRecipient {
75 recipient: BytesMut,
76}
77
78impl DeleteRecipient {
79 const CODE: u8 = b'-';
80
81 #[must_use]
83 pub fn new(recipient: &[u8]) -> Self {
84 Self {
85 recipient: BytesMut::from_iter(recipient),
86 }
87 }
88
89 #[must_use]
91 pub fn recipient(&self) -> Cow<str> {
92 String::from_utf8_lossy(&self.recipient)
93 }
94}
95
96impl Parsable for DeleteRecipient {
97 const CODE: u8 = Self::CODE;
98
99 fn parse(mut buffer: BytesMut) -> Result<Self, ProtocolError> {
100 let Some(recipient) = buffer.delimited(0) else {
101 return Err(InvalidData::new(
102 "Received delete recipient package without null byte terminating it",
103 buffer,
104 )
105 .into());
106 };
107
108 Ok(Self { recipient })
109 }
110}
111
112impl Writable for DeleteRecipient {
113 fn write(&self, buffer: &mut BytesMut) {
114 buffer.extend_from_slice(&self.recipient);
115 buffer.put_u8(0);
116 }
117
118 fn len(&self) -> usize {
119 self.recipient.len() + 1
120 }
121
122 fn code(&self) -> u8 {
123 Self::CODE
124 }
125
126 fn is_empty(&self) -> bool {
127 self.len() == 0
128 }
129}
130
131#[cfg(test)]
132mod test {
133 use super::*;
134
135 #[test]
136 fn test_add_recipient() {
137 let mut buffer = BytesMut::new();
138 let add_rcpt = AddRecipient {
139 recipient: BytesMut::from("alex@gmail"),
140 };
141 add_rcpt.write(&mut buffer);
142
143 assert_eq!(buffer.len(), add_rcpt.len());
144 assert_eq!(buffer, BytesMut::from("alex@gmail\0"));
145 }
146
147 #[test]
148 fn test_delete_recipient() {
149 let mut buffer = BytesMut::new();
150 let add_rcpt = AddRecipient {
151 recipient: BytesMut::from("alex@gmail"),
152 };
153 add_rcpt.write(&mut buffer);
154
155 assert_eq!(buffer.len(), add_rcpt.len());
156 assert_eq!(buffer, BytesMut::from("alex@gmail\0"));
157 }
158}