use crate::fields::{FieldMap as Map, FieldValue as Value};
use crate::kvp::{KeyValuePair, KvpValue};
use crate::varint::VarInt;
#[cfg(feature = "draft07")]
fn d07_setup_param_name(key: u64) -> Option<&'static str> {
match key {
0x00 => Some("role"),
0x01 => Some("path"),
0x02 => Some("max_subscribe_id"),
_ => None,
}
}
fn d07_message_param_name(key: u64) -> Option<&'static str> {
match key {
0x02 => Some("authorization_info"),
0x03 => Some("delivery_timeout"),
0x04 => Some("max_cache_duration"),
_ => None,
}
}
#[cfg(feature = "draft07")]
fn d07_setup_is_varint(key: u64) -> bool {
matches!(key, 0x00 | 0x02) }
#[cfg(any(feature = "draft08", feature = "draft09", feature = "draft10"))]
fn d08_setup_param_name(key: u64) -> Option<&'static str> {
match key {
0x01 => Some("path"),
0x02 => Some("max_subscribe_id"),
_ => None,
}
}
#[cfg(any(feature = "draft08", feature = "draft09", feature = "draft10"))]
fn d08_setup_is_varint(key: u64) -> bool {
key == 0x02 }
fn d07_msg_is_varint(key: u64) -> bool {
matches!(key, 0x03 | 0x04) }
fn kvp_to_json_d07_inner(
params: &[KeyValuePair],
name_fn: fn(u64) -> Option<&'static str>,
is_varint_fn: fn(u64) -> bool,
) -> Value {
let mut obj = Map::new();
let mut unknown = Vec::new();
for p in params {
let key = p.key.into_inner();
if let Some(name) = name_fn(key) {
match &p.value {
KvpValue::Bytes(b) if is_varint_fn(key) => {
let value = match VarInt::decode(&mut &b[..]) {
Ok(v) => Value::Uint(v.into_inner()),
Err(_) => Value::Bytes(b.to_vec()),
};
obj.insert(name.to_string(), value);
}
KvpValue::Bytes(b) => {
obj.insert(
name.to_string(),
Value::Text(String::from_utf8_lossy(b).into_owned()),
);
}
KvpValue::Varint(v) => {
obj.insert(name.to_string(), Value::Uint(v.into_inner()));
}
}
} else {
let mut entry = Map::new();
entry.insert("id".to_string(), Value::Text(format!("0x{:x}", key)));
match &p.value {
KvpValue::Bytes(b) => {
entry.insert("length".to_string(), Value::Uint(b.len() as u64));
entry.insert("raw_hex".to_string(), Value::Bytes(b.to_vec()));
}
KvpValue::Varint(v) => {
entry.insert("length".to_string(), Value::Uint(v.into_inner()));
}
}
unknown.push(Value::Map(entry));
}
}
if !unknown.is_empty() {
obj.insert("unknown".to_string(), Value::Array(unknown));
}
Value::Map(obj)
}
#[cfg(feature = "draft07")]
pub fn kvp_to_json_d07_setup(params: &[KeyValuePair]) -> Value {
kvp_to_json_d07_inner(params, d07_setup_param_name, d07_setup_is_varint)
}
pub fn kvp_to_json_d07(params: &[KeyValuePair]) -> Value {
kvp_to_json_d07_inner(params, d07_message_param_name, d07_msg_is_varint)
}
#[cfg(any(feature = "draft08", feature = "draft09", feature = "draft10"))]
pub fn kvp_to_json_d08_setup(params: &[KeyValuePair]) -> Value {
kvp_to_json_d07_inner(params, d08_setup_param_name, d08_setup_is_varint)
}