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
mod decoder;
mod encoder;
use indexmap::IndexMap;
use std::str::FromStr;
use crate::Error;
pub use decoder::Decoder;
pub use encoder::Encoder;
pub use yooper_derive::{FromHeaders, FromPacket, ToHeaders, ToPacket};
const REQUEST_LINE_NOTIFY: &str = "NOTIFY * HTTP/1.1";
const REQUEST_LINE_M_SEARCH: &str = "M-SEARCH * HTTP/1.1";
const REQUEST_LINE_OK: &str = "HTTP/1.1 200 OK";
#[derive(PartialEq, Debug)]
pub enum PacketType {
MSearch,
Notify,
Ok,
}
impl ToString for PacketType {
fn to_string(&self) -> String {
match self {
Self::MSearch => REQUEST_LINE_M_SEARCH,
Self::Notify => REQUEST_LINE_NOTIFY,
Self::Ok => REQUEST_LINE_OK,
}
.to_string()
}
}
impl FromStr for PacketType {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
REQUEST_LINE_OK => Ok(Self::Ok),
REQUEST_LINE_NOTIFY => Ok(Self::Notify),
REQUEST_LINE_M_SEARCH => Ok(Self::MSearch),
s => Err(Error::ParseFailure(format!("Unknown request line {}", s))),
}
}
}
pub type Headers = IndexMap<String, String>;
#[derive(PartialEq, Debug)]
pub struct Packet {
pub typ: PacketType,
pub headers: Headers,
}
impl Packet {
#[cfg(test)]
pub(crate) fn new_from_literal(typ: PacketType, headers: Vec<(&str, &str)>) -> Self {
let headers = headers
.into_iter()
.map(|(k, v)| (k.into(), v.into()))
.collect();
Self { typ, headers }
}
}
pub trait FromPacket: std::marker::Sized {
fn from_packet(msg: &Packet) -> Result<Self, crate::errors::Error>;
}
pub trait ToPacket {
fn to_packet(&self) -> Packet;
}
pub trait FromHeaders: std::marker::Sized {
fn from_headers(headers: &Headers) -> Result<Self, crate::errors::Error>;
}
pub trait ToHeaders {
fn to_headers(&self) -> Headers;
}