I'm writing a parser for SSDP
, which is a part of UPnP. It uses a wire format that resembels an extremely constrained HTTP1/.1 over UDP. There's only a half dozen message types, so I figured I could use an Enum to represent all messages.
I know I'm going to be writing my own serializer/deserializer, and I'm fine with that. Aside from the special case first line (the request line, i.e. `NOTIFY * HTTP/1.1", it's a pretty standard key/value mapping.
One wrinkle is that there isn't a single header that decides the message type. It's a bit more complicated, depending on the HTTP method and a header:
+-----------+
|HTTP Method|
+--+----+---+
| |
| | M-Search +----------------+
| +-------->-+ Message::Search|
| +----------------+
|
| Notify +----------------+
+------------->-+ NTS header? |
++-----+------+--+
| | |
| | |ssdp:aliVe +--------------------+
| | +------------>+Message::Alive |
| | +--------------------+
| |
| | ssdp:byebye +--------------------+
| +------------------->+Message::Unavailable|
| +--------------------+
|
| ssdp:update +--------------------+
+------------------------->+Message::Update |
+--------------------+
Here's an example message, captured off my home network:
NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=3600
LOCATION: http://192.168.7.238:54216/RootDevice.xml
NT: urn:schemas-upnp-org:service:ConnectionManager:1
NTS: ssdp:alive
SERVER: Windows 10/10.0 UPnP/1.0 Azureus/5.7.6.0
USN: uuid:07853410-ccef-9e3c-de6a-410b371182eb::urn:schemas-upnp-org:service:ConnectionManager:1
and here's the enum variant I want to serialize that into:
enum Message {
Available {
max_age: u32,
location: String,
secure_location: Option<String>,
notification_type: String,
server: String,
unique_service_name: String,
boot_id: i32,
config_id: i32,
search_port: Option<u16>,
},
// more message types
}
Is there any way to make this fit neatly into the serde data model? or am I trying to shove a serde peg into a round hole?