use std::borrow::Cow;
use std::collections::HashMap;
use std::sync::Arc;
pub trait Tagged {
fn tag() -> Cow<'static, str>;
fn tag_unique_factor() -> String;
}
impl<'a, T: Tagged + 'a> Tagged for &'a T {
fn tag() -> Cow<'static, str> {
T::tag()
}
fn tag_unique_factor() -> String {
T::tag_unique_factor()
}
}
impl<T: Tagged> Tagged for Arc<T> {
fn tag() -> Cow<'static, str> {
T::tag()
}
fn tag_unique_factor() -> String {
T::tag_unique_factor()
}
}
impl<T: Tagged> Tagged for Box<T> {
fn tag() -> Cow<'static, str> {
T::tag()
}
fn tag_unique_factor() -> String {
T::tag_unique_factor()
}
}
impl<T: Tagged> Tagged for Option<T> {
fn tag() -> Cow<'static, str> {
Cow::Owned(format!("option({})", T::tag()))
}
fn tag_unique_factor() -> String {
format!("[(),{}]", T::tag())
}
}
impl<T: Tagged> Tagged for Vec<T> {
fn tag() -> Cow<'static, str> {
Cow::Owned(format!("vec({})", T::tag()))
}
fn tag_unique_factor() -> String {
format!("vec({})", T::tag())
}
}
impl<K: Tagged, V: Tagged> Tagged for HashMap<K, V> {
fn tag() -> Cow<'static, str> {
Cow::Owned(format!("map({},{})", K::tag(), V::tag()))
}
fn tag_unique_factor() -> String {
format!("map({},{})", K::tag(), V::tag())
}
}
impl<const N: usize, T: Tagged> Tagged for [T; N] {
fn tag() -> Cow<'static, str> {
Cow::Owned(format!("array({},{})", T::tag(), N))
}
fn tag_unique_factor() -> String {
format!("array({},{})", T::tag(), N)
}
}