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
use bytes::BytesMut;
use tokio_util::codec::{Decoder, Encoder};
use crate::error;
use crate::line::LineCodec;
use crate::message::Message;
pub struct IrcCodec {
inner: LineCodec,
}
impl IrcCodec {
pub fn new(label: &str) -> error::Result<IrcCodec> {
LineCodec::new(label).map(|codec| IrcCodec { inner: codec })
}
pub fn sanitize(mut data: String) -> String {
if let Some((pos, len)) = ["\r\n", "\r", "\n"]
.iter()
.flat_map(|needle| data.find(needle).map(|pos| (pos, needle.len())))
.min_by_key(|&(pos, _)| pos)
{
data.truncate(pos + len);
}
data
}
}
impl Decoder for IrcCodec {
type Item = Message;
type Error = error::ProtocolError;
fn decode(&mut self, src: &mut BytesMut) -> error::Result<Option<Message>> {
self.inner
.decode(src)
.and_then(|res| res.map_or(Ok(None), |msg| msg.parse::<Message>().map(Some)))
}
}
impl Encoder<Message> for IrcCodec {
type Error = error::ProtocolError;
fn encode(&mut self, msg: Message, dst: &mut BytesMut) -> error::Result<()> {
self.inner.encode(IrcCodec::sanitize(msg.to_string()), dst)
}
}