use std::collections::BTreeMap;
use serde_cbor::Value as CborValue;
#[extension(pub trait CborValueGetters)]
impl CborValue {
fn as_array(&self) -> Option<&[CborValue]> {
let Self::Array(it) = self else { return None };
Some(it)
}
fn as_array_mut(&mut self) -> Option<&mut Vec<CborValue>> {
let Self::Array(it) = self else { return None };
Some(it)
}
fn as_bool(&self) -> Option<bool> {
let &Self::Bool(it) = self else { return None };
Some(it)
}
fn as_f64(&self) -> Option<f64> {
let &Self::Float(it) = self else { return None };
Some(it)
}
fn as_i64(&self) -> Option<i64> {
let &Self::Integer(it) = self else {
return None;
};
it.try_into().ok()
}
fn as_null(&self) -> Option<()> {
matches!(self, Self::Null).then(|| ())
}
fn as_object(&self) -> Option<&BTreeMap<CborValue, CborValue>> {
let Self::Map(it) = self else { return None };
Some(it)
}
fn as_object_mut(&mut self) -> Option<&mut BTreeMap<CborValue, CborValue>> {
let Self::Map(it) = self else { return None };
Some(it)
}
fn as_str(&self) -> Option<&str> {
let Self::Text(it) = self else { return None };
Some(it)
}
fn as_u64(&self) -> Option<u64> {
let &Self::Integer(it) = self else {
return None;
};
it.try_into().ok()
}
fn get(&self, i: impl sealed::Index) -> Option<&CborValue> {
i.get(self)
}
fn get_mut(&mut self, i: impl sealed::Index) -> Option<&mut CborValue> {
i.get_mut(self)
}
}
mod sealed {
use super::*;
pub trait Index {
fn get(self, value: &CborValue) -> Option<&CborValue>;
fn get_mut(self, value: &mut CborValue) -> Option<&mut CborValue>;
}
impl Index for &str {
fn get(self, value: &CborValue) -> Option<&CborValue> {
value.as_object()?.get(&CborValue::Text(self.into()))
}
fn get_mut(self, value: &mut CborValue) -> Option<&mut CborValue> {
value
.as_object_mut()?
.get_mut(&CborValue::Text(self.into()))
}
}
impl Index for &String {
fn get(self, value: &CborValue) -> Option<&CborValue> {
<&str as Index>::get(self, value)
}
fn get_mut(self, value: &mut CborValue) -> Option<&mut CborValue> {
<&str as Index>::get_mut(self, value)
}
}
impl Index for usize {
fn get(self, value: &CborValue) -> Option<&CborValue> {
value.as_array()?.get(self)
}
fn get_mut(self, value: &mut CborValue) -> Option<&mut CborValue> {
value.as_array_mut()?.get_mut(self)
}
}
}