use std::{
borrow::Cow,
collections::{BTreeMap, BTreeSet, LinkedList, VecDeque},
rc::Rc,
sync::Arc,
};
use crate::error::Result;
pub trait LabelSetEncoder {
fn encode(&mut self, label: &dyn EncodeLabel) -> Result<()>;
}
pub trait EncodeLabelSet {
fn encode(&self, encoder: &mut dyn LabelSetEncoder) -> Result<()>;
fn is_empty(&self) -> bool {
false
}
}
impl EncodeLabelSet for () {
fn encode(&self, _encoder: &mut dyn LabelSetEncoder) -> Result<()> {
Ok(())
}
fn is_empty(&self) -> bool {
true
}
}
macro_rules! impl_encode_label_set_for_container {
(<$($desc:tt)+) => (
impl <$($desc)+ {
#[inline]
fn encode(&self, encoder: &mut dyn LabelSetEncoder) -> Result<()> {
for label in self.iter() {
encoder.encode(label)?;
}
Ok(())
}
#[inline]
fn is_empty(&self) -> bool {
self.len() == 0
}
}
)
}
impl_encode_label_set_for_container! { <T: EncodeLabel> EncodeLabelSet for [T] }
impl_encode_label_set_for_container! { <T: EncodeLabel, const N: usize> EncodeLabelSet for [T; N] }
impl_encode_label_set_for_container! { <T: EncodeLabel> EncodeLabelSet for Vec<T> }
impl_encode_label_set_for_container! { <T: EncodeLabel> EncodeLabelSet for VecDeque<T> }
impl_encode_label_set_for_container! { <T: EncodeLabel> EncodeLabelSet for LinkedList<T> }
impl_encode_label_set_for_container! { <T: EncodeLabel> EncodeLabelSet for BTreeSet<T> }
impl<K: EncodeLabelName, V: EncodeLabelValue> EncodeLabelSet for BTreeMap<K, V> {
fn encode(&self, encoder: &mut dyn LabelSetEncoder) -> Result<()> {
for label in self.iter() {
encoder.encode(&label)?;
}
Ok(())
}
fn is_empty(&self) -> bool {
BTreeMap::is_empty(self)
}
}
macro_rules! impl_enable_label_set_for_deref {
(<$($desc:tt)+) => (
impl <$($desc)+ {
#[inline]
fn encode(&self, encoder: &mut dyn LabelSetEncoder) -> Result<()> {
(**self).encode(encoder)
}
#[inline]
fn is_empty(&self) -> bool {
(**self).is_empty()
}
}
)
}
impl_enable_label_set_for_deref! { <'a, T> EncodeLabelSet for &'a T where T: ?Sized + EncodeLabelSet }
impl_enable_label_set_for_deref! { <'a, T> EncodeLabelSet for &'a mut T where T: ?Sized + EncodeLabelSet }
impl_enable_label_set_for_deref! { <'a, T> EncodeLabelSet for Cow<'a, T> where T: ?Sized + EncodeLabelSet + ToOwned }
impl_enable_label_set_for_deref! { <T> EncodeLabelSet for Box<T> where T: ?Sized + EncodeLabelSet }
impl_enable_label_set_for_deref! { <T> EncodeLabelSet for Rc<T> where T: ?Sized + EncodeLabelSet }
impl_enable_label_set_for_deref! { <T> EncodeLabelSet for Arc<T> where T: ?Sized + EncodeLabelSet }
pub trait LabelEncoder {
fn encode_label_name(&mut self, name: &str) -> Result<()>;
fn encode_str_value(&mut self, value: &str) -> Result<()>;
fn encode_bool_value(&mut self, value: bool) -> Result<()>;
fn encode_i8_value(&mut self, value: i8) -> Result<()>;
fn encode_i16_value(&mut self, value: i16) -> Result<()>;
fn encode_i32_value(&mut self, value: i32) -> Result<()>;
fn encode_i64_value(&mut self, value: i64) -> Result<()>;
fn encode_i128_value(&mut self, value: i128) -> Result<()>;
fn encode_isize_value(&mut self, value: isize) -> Result<()>;
fn encode_u8_value(&mut self, value: u8) -> Result<()>;
fn encode_u16_value(&mut self, value: u16) -> Result<()>;
fn encode_u32_value(&mut self, value: u32) -> Result<()>;
fn encode_u64_value(&mut self, value: u64) -> Result<()>;
fn encode_u128_value(&mut self, value: u128) -> Result<()>;
fn encode_usize_value(&mut self, value: usize) -> Result<()>;
fn encode_f32_value(&mut self, value: f32) -> Result<()>;
fn encode_f64_value(&mut self, value: f64) -> Result<()>;
}
pub trait EncodeLabel {
fn encode(&self, encoder: &mut dyn LabelEncoder) -> Result<()>;
}
impl<N, V> EncodeLabel for (N, V)
where
N: EncodeLabelName,
V: EncodeLabelValue,
{
fn encode(&self, encoder: &mut dyn LabelEncoder) -> Result<()> {
let (name, value) = self;
if value.skip_encoding() {
return Ok(());
}
name.encode(encoder)?;
value.encode(encoder)?;
Ok(())
}
}
pub trait EncodeLabelName {
fn encode(&self, encoder: &mut dyn LabelEncoder) -> Result<()>;
}
impl EncodeLabelName for str {
fn encode(&self, encoder: &mut dyn LabelEncoder) -> Result<()> {
encoder.encode_label_name(self)
}
}
impl EncodeLabelName for String {
fn encode(&self, encoder: &mut dyn LabelEncoder) -> Result<()> {
encoder.encode_label_name(self)
}
}
macro_rules! impl_encode_label_name_for_deref {
(<$($desc:tt)+) => (
impl <$($desc)+ {
#[inline]
fn encode(&self, encoder: &mut dyn LabelEncoder) -> Result<()> {
(**self).encode(encoder)
}
}
)
}
impl_encode_label_name_for_deref! { <'a, T> EncodeLabelName for &'a T where T: ?Sized + EncodeLabelName }
impl_encode_label_name_for_deref! { <'a, T> EncodeLabelName for &'a mut T where T: ?Sized + EncodeLabelName }
impl_encode_label_name_for_deref! { <'a, T> EncodeLabelName for Cow<'a, T> where T: ?Sized + EncodeLabelName + ToOwned }
impl_encode_label_name_for_deref! { <T> EncodeLabelName for Box<T> where T: ?Sized + EncodeLabelName }
impl_encode_label_name_for_deref! { <T> EncodeLabelName for Rc<T> where T: ?Sized + EncodeLabelName }
impl_encode_label_name_for_deref! { <T> EncodeLabelName for Arc<T> where T: ?Sized + EncodeLabelName }
pub trait EncodeLabelValue {
fn encode(&self, encoder: &mut dyn LabelEncoder) -> Result<()>;
fn skip_encoding(&self) -> bool {
false
}
}
impl EncodeLabelValue for str {
#[inline]
fn encode(&self, encoder: &mut dyn LabelEncoder) -> Result<()> {
encoder.encode_str_value(self)
}
}
impl EncodeLabelValue for String {
#[inline]
fn encode(&self, encoder: &mut dyn LabelEncoder) -> Result<()> {
encoder.encode_str_value(self)
}
}
macro_rules! impl_encode_label_value_for {
($($ty:ty),*) => (
paste::paste! { $(
impl EncodeLabelValue for $ty {
#[inline]
fn encode(&self, encoder: &mut dyn LabelEncoder) -> Result<()> {
encoder.[<encode_ $ty _value>](*self)
}
}
)* }
)
}
impl_encode_label_value_for! {
bool,
i8, i16, i32, i64, i128, isize,
u8, u16, u32, u64, u128, usize,
f32, f64
}
impl<T> EncodeLabelValue for Option<T>
where
T: EncodeLabelValue,
{
#[inline]
fn encode(&self, encoder: &mut dyn LabelEncoder) -> Result<()> {
match self {
Some(value) => value.encode(encoder),
None => Ok(()),
}
}
#[inline]
fn skip_encoding(&self) -> bool {
self.is_none()
}
}
macro_rules! impl_encode_label_value_for_deref {
(<$($desc:tt)+) => (
impl <$($desc)+ {
#[inline]
fn encode(&self, encoder: &mut dyn LabelEncoder) -> Result<()> {
(**self).encode(encoder)
}
#[inline]
fn skip_encoding(&self) -> bool {
(**self).skip_encoding()
}
}
)
}
impl_encode_label_value_for_deref! { <'a, T> EncodeLabelValue for &'a T where T: ?Sized + EncodeLabelValue }
impl_encode_label_value_for_deref! { <'a, T> EncodeLabelValue for &'a mut T where T: ?Sized + EncodeLabelValue }
impl_encode_label_value_for_deref! { <'a, T> EncodeLabelValue for Cow<'a, T> where T: ?Sized + EncodeLabelValue + ToOwned }
impl_encode_label_value_for_deref! { <T> EncodeLabelValue for Box<T> where T: ?Sized + EncodeLabelValue }
impl_encode_label_value_for_deref! { <T> EncodeLabelValue for Rc<T> where T: ?Sized + EncodeLabelValue }
impl_encode_label_value_for_deref! { <T> EncodeLabelValue for Arc<T> where T: ?Sized + EncodeLabelValue }