use bytes::BufMut;
use crate::encoding;
use crate::transport::TransportError;
#[derive(Clone, Debug, serde::Serialize)]
#[non_exhaustive]
pub enum EncodingName {
#[serde(rename = "proto")]
Protobuf,
}
impl From<encoding::Name> for EncodingName {
fn from(name: encoding::Name) -> Self {
match name {
encoding::Name::Protobuf => EncodingName::Protobuf,
}
}
}
#[derive(Clone, Debug, serde::Serialize)]
pub enum CompressionType {
#[serde(rename = "per-message")]
PerMessage,
#[serde(rename = "context-takeover")]
ContextTakeover,
}
#[derive(Clone, Debug, serde::Serialize)]
#[non_exhaustive]
pub struct NegotiationParams {
#[serde(rename = "enc")]
pub encoding_name: EncodingName,
#[serde(rename = "comp", skip_serializing_if = "Option::is_none")]
pub compression_type: Option<CompressionType>,
#[serde(rename = "clevel", skip_serializing_if = "Option::is_none")]
pub compression_level: Option<i8>,
#[serde(rename = "cwinbits", skip_serializing_if = "Option::is_none")]
pub compression_window_bits: Option<u8>,
}
impl NegotiationParams {
pub(crate) fn to_uri_query_string(&self) -> Result<String, TransportError> {
serde_qs::to_string(&self).map_err(TransportError::new)
}
pub(crate) fn to_bytes(&self) -> Result<Vec<u8>, TransportError> {
use serde_json::Value;
let mut buf = Vec::new();
let value = serde_json::to_value(self).unwrap();
let map = value.as_object().unwrap();
for (k, v) in map.iter() {
let v = match v {
Value::Null => continue,
Value::String(s) => s.clone(),
_ => v.to_string(),
};
buf.put_u16(
k.len()
.try_into()
.map_err(|_| TransportError::from_msg("too long key for negotiation"))?,
);
buf.put(k.as_bytes());
buf.put_u16(
v.len()
.try_into()
.map_err(|_| TransportError::from_msg("too long value for negotiation"))?,
);
buf.put(v.as_bytes());
}
Ok(buf)
}
}