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
use super::{AcceptedReply, RejectedReply};
use crate::bytes_ext::BytesReaderExt;
use crate::Error;
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use bytes::Bytes;
use std::convert::TryFrom;
use std::io::Cursor;
const REPLY_ACCEPTED: u32 = 0;
const REPLY_DENIED: u32 = 1;
#[derive(Debug, PartialEq)]
pub enum ReplyBody<T, P>
where
T: AsRef<[u8]>,
P: AsRef<[u8]>,
{
Accepted(AcceptedReply<T, P>),
Denied(RejectedReply),
}
impl<'a> ReplyBody<&'a [u8], &'a [u8]> {
pub(crate) fn from_cursor(r: &mut Cursor<&'a [u8]>) -> Result<Self, Error> {
match r.read_u32::<BigEndian>()? {
REPLY_ACCEPTED => Ok(ReplyBody::Accepted(AcceptedReply::from_cursor(r)?)),
REPLY_DENIED => Ok(ReplyBody::Denied(RejectedReply::from_cursor(r)?)),
v => Err(Error::InvalidReplyType(v)),
}
}
}
impl<T, P> ReplyBody<T, P>
where
T: AsRef<[u8]>,
P: AsRef<[u8]>,
{
pub fn serialise_into(&self, buf: &mut Cursor<Vec<u8>>) -> Result<(), std::io::Error> {
match self {
ReplyBody::Accepted(b) => {
buf.write_u32::<BigEndian>(REPLY_ACCEPTED)?;
b.serialise_into(buf)
}
ReplyBody::Denied(b) => {
buf.write_u32::<BigEndian>(REPLY_DENIED)?;
b.serialise_into(buf)
}
}
}
pub fn serialised_len(&self) -> u32 {
let mut len = 0;
len += 4;
len += match self {
ReplyBody::Accepted(b) => b.serialised_len(),
ReplyBody::Denied(b) => b.serialised_len(),
};
len
}
}
impl<'a> TryFrom<&'a [u8]> for ReplyBody<&'a [u8], &'a [u8]> {
type Error = Error;
fn try_from(v: &'a [u8]) -> Result<Self, Self::Error> {
let mut c = Cursor::new(v);
ReplyBody::from_cursor(&mut c)
}
}
impl TryFrom<Bytes> for ReplyBody<Bytes, Bytes> {
type Error = Error;
fn try_from(mut v: Bytes) -> Result<Self, Self::Error> {
match v.try_u32()? {
REPLY_ACCEPTED => Ok(ReplyBody::Accepted(AcceptedReply::try_from(v)?)),
REPLY_DENIED => Ok(ReplyBody::Denied(RejectedReply::try_from(v)?)),
v => Err(Error::InvalidReplyType(v)),
}
}
}