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
use bytes::{Buf, Bytes};

/// represent the request/response message
pub enum Message<T, Data: Buf = Bytes> {
    Header(T),
    Payload(PayloadItem<Data>),
}

/// payload item produced from payload decoder
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum PayloadItem<Data: Buf = Bytes> {
    Chunk(Data),
    Eof,
}

/// represent the payload size
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum PayloadSize {
    Length(u64),
    Chunked,
    Empty,
}

impl<T> Message<T> {
    pub fn is_payload(&self) -> bool {
        match self {
            Message::Header(_) => false,
            Message::Payload(_) => true,
        }
    }

    pub fn is_header(&self) -> bool {
        match self {
            Message::Header(_) => true,
            Message::Payload(_) => false,
        }
    }

    pub fn into_payload_item(self) -> Option<PayloadItem> {
        match self {
            Message::Header(_) => None,
            Message::Payload(payload_item) => Some(payload_item),
        }
    }
}

impl<T> From<Bytes> for Message<T> {
    fn from(bytes: Bytes) -> Self {
        Self::Payload(PayloadItem::Chunk(bytes))
    }
}

impl<D: Buf> PayloadItem<D> {
    pub fn is_eof(&self) -> bool {
        match self {
            PayloadItem::Chunk(_) => false,
            PayloadItem::Eof => true,
        }
    }

    pub fn is_chunk(&self) -> bool {
        match self {
            PayloadItem::Chunk(_) => true,
            PayloadItem::Eof => false,
        }
    }
}

impl PayloadItem {
    pub fn as_bytes(&self) -> Option<&Bytes> {
        match self {
            PayloadItem::Chunk(bytes) => Some(bytes),
            PayloadItem::Eof => None,
        }
    }

    pub fn as_mut_bytes(&mut self) -> Option<&mut Bytes> {
        match self {
            PayloadItem::Chunk(bytes) => Some(bytes),
            PayloadItem::Eof => None,
        }
    }

    pub fn into_bytes(self) -> Option<Bytes> {
        match self {
            PayloadItem::Chunk(bytes) => Some(bytes),
            PayloadItem::Eof => None,
        }
    }
}