use crate::{
SpopFrame,
frame::{FramePayload, FrameType, Metadata},
types::TypedData,
};
use std::{borrow::Cow, collections::HashMap, convert::TryFrom};
#[derive(Debug)]
pub struct HaproxyDisconnect {
pub status_code: u32,
pub message: String,
}
impl HaproxyDisconnect {
#[must_use]
pub fn to_kv_list(&self) -> HashMap<String, TypedData> {
let mut map = HashMap::new();
map.insert(
"status-code".to_string(),
TypedData::UInt32(self.status_code),
);
map.insert(
"message".to_string(),
TypedData::String(self.message.clone()),
);
map
}
}
#[derive(Debug)]
pub struct HaproxyDisconnectFrame {
pub metadata: Metadata,
pub payload: HaproxyDisconnect,
}
impl SpopFrame for HaproxyDisconnectFrame {
fn frame_type(&self) -> &FrameType {
&FrameType::HaproxyDisconnect
}
fn metadata(&self) -> Cow<'_, Metadata> {
Cow::Borrowed(&self.metadata)
}
fn payload(&self) -> FramePayload<'_> {
FramePayload::KVList(self.payload.to_kv_list())
}
}
impl TryFrom<FramePayload<'_>> for HaproxyDisconnect {
type Error = String;
fn try_from(payload: FramePayload) -> Result<Self, Self::Error> {
if let FramePayload::KVList(kv_list) = payload {
let status_code = kv_list
.get("status-code")
.and_then(|v| match v {
TypedData::UInt32(val) => Some(*val),
_ => None,
})
.ok_or_else(|| "Missing or invalid status_code".to_string())?;
let message = kv_list
.get("message")
.and_then(|v| match v {
TypedData::String(val) => Some(val.clone()),
_ => None,
})
.ok_or_else(|| "Missing message".to_string())?;
Ok(Self {
status_code,
message,
})
} else {
Err("Invalid FramePayload type, expected KVList.".to_string())
}
}
}