use crate::Identifier;
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{any::type_name, collections::BTreeMap};
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
#[non_exhaustive]
pub struct CustomTypeInfo {
pub type_name: Identifier,
pub display_name: Identifier,
#[cfg(feature = "metadata")]
pub comments: crate::StaticVec<crate::SmartString>,
}
#[derive(Debug, Clone, Hash)]
pub struct CustomTypesCollection(BTreeMap<Identifier, Box<CustomTypeInfo>>);
impl Default for CustomTypesCollection {
#[inline(always)]
fn default() -> Self {
Self::new()
}
}
impl CustomTypesCollection {
#[inline(always)]
pub const fn new() -> Self {
Self(BTreeMap::new())
}
#[inline(always)]
pub fn clear(&mut self) {
self.0.clear();
}
#[inline(always)]
pub fn add(&mut self, type_name: impl Into<Identifier>, name: impl Into<Identifier>) {
let type_name = type_name.into();
let custom_type = CustomTypeInfo {
type_name: type_name.clone(),
display_name: name.into(),
#[cfg(feature = "metadata")]
comments: <_>::default(),
};
self.add_raw(type_name, custom_type);
}
#[cfg(feature = "metadata")]
#[inline(always)]
pub fn add_with_comments<C: Into<crate::SmartString>>(
&mut self,
type_name: impl Into<Identifier>,
name: impl Into<Identifier>,
comments: impl IntoIterator<Item = C>,
) {
let type_name = type_name.into();
let custom_type = CustomTypeInfo {
type_name: type_name.clone(),
display_name: name.into(),
comments: comments.into_iter().map(Into::into).collect(),
};
self.add_raw(type_name, custom_type);
}
#[inline(always)]
pub fn add_type<T>(&mut self, name: &str) {
self.add_raw(
type_name::<T>(),
CustomTypeInfo {
type_name: type_name::<T>().into(),
display_name: name.into(),
#[cfg(feature = "metadata")]
comments: <_>::default(),
},
);
}
#[cfg(feature = "metadata")]
#[inline(always)]
pub fn add_type_with_comments<T>(&mut self, name: &str, comments: &[&str]) {
self.add_raw(
type_name::<T>(),
CustomTypeInfo {
type_name: type_name::<T>().into(),
display_name: name.into(),
#[cfg(feature = "metadata")]
comments: comments.iter().map(|&s| s.into()).collect(),
},
);
}
#[inline(always)]
pub fn add_raw(&mut self, type_name: impl Into<Identifier>, custom_type: CustomTypeInfo) {
self.0.insert(type_name.into(), custom_type.into());
}
#[inline(always)]
#[must_use]
pub fn get(&self, key: &str) -> Option<&CustomTypeInfo> {
self.0.get(key).map(<_>::as_ref)
}
#[inline(always)]
pub fn iter(&self) -> impl Iterator<Item = (&str, &CustomTypeInfo)> {
self.0.iter().map(|(k, v)| (k.as_str(), v.as_ref()))
}
}