use crate::{
MAX_ATTRIBUTE_DEFINITIONS, MAX_ATTRIBUTE_VALUES,
attribute::{
AttributeDefinition, AttributeDefinitions as AttrDefsVec, AttributeObjectType,
AttributeTarget, AttributeValue,
},
compat::{BTreeMap, Name},
};
type DefaultsMap = BTreeMap<Name, AttributeValue, MAX_ATTRIBUTE_DEFINITIONS>;
type ValuesMap = BTreeMap<(Name, AttributeTarget), AttributeValue, MAX_ATTRIBUTE_VALUES>;
#[derive(Debug, Clone, PartialEq, Default)]
pub struct AttributeDefinitionsMap {
definitions: AttrDefsVec,
}
impl AttributeDefinitionsMap {
#[allow(dead_code)]
pub(crate) fn new() -> Self {
Self {
definitions: AttrDefsVec::new(),
}
}
pub(crate) fn from_vec(definitions: AttrDefsVec) -> Self {
Self { definitions }
}
#[inline]
#[must_use = "iterator is lazy and does nothing unless consumed"]
pub fn iter(&self) -> impl Iterator<Item = &AttributeDefinition> {
self.definitions.as_slice().iter()
}
#[inline]
#[must_use = "return value should be used"]
pub fn len(&self) -> usize {
self.definitions.len()
}
#[inline]
#[must_use = "return value should be used"]
pub fn is_empty(&self) -> bool {
self.definitions.is_empty()
}
#[inline]
#[must_use = "return value should be used"]
pub fn get(&self, name: &str) -> Option<&AttributeDefinition> {
self.definitions.as_slice().iter().find(|def| def.name() == name)
}
#[inline]
#[must_use = "return value should be used"]
pub fn get_for_type(
&self,
name: &str,
object_type: AttributeObjectType,
) -> Option<&AttributeDefinition> {
self.definitions
.as_slice()
.iter()
.find(|def| def.name() == name && def.object_type() == object_type)
}
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct AttributeDefaultsMap {
defaults: DefaultsMap,
}
impl AttributeDefaultsMap {
#[allow(dead_code)]
pub(crate) fn new() -> Self {
Self {
defaults: DefaultsMap::new(),
}
}
pub(crate) fn from_map(defaults: DefaultsMap) -> Self {
Self { defaults }
}
#[inline]
#[must_use = "iterator is lazy and does nothing unless consumed"]
pub fn iter(&self) -> impl Iterator<Item = (&str, &AttributeValue)> {
self.defaults.iter().map(|(name, value)| (name.as_str(), value))
}
#[inline]
#[must_use = "return value should be used"]
pub fn len(&self) -> usize {
self.defaults.len()
}
#[inline]
#[must_use = "return value should be used"]
pub fn is_empty(&self) -> bool {
self.defaults.is_empty()
}
#[inline]
#[must_use = "return value should be used"]
pub fn get(&self, name: &str) -> Option<&AttributeValue> {
self.defaults.iter().find(|(n, _)| n.as_str() == name).map(|(_, v)| v)
}
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct AttributeValuesMap {
values: ValuesMap,
}
impl AttributeValuesMap {
#[allow(dead_code)]
pub(crate) fn new() -> Self {
Self {
values: ValuesMap::new(),
}
}
pub(crate) fn from_map(values: ValuesMap) -> Self {
Self { values }
}
#[inline]
#[must_use = "iterator is lazy and does nothing unless consumed"]
pub fn iter(&self) -> impl Iterator<Item = ((&str, &AttributeTarget), &AttributeValue)> {
self.values
.iter()
.map(|((name, target), value)| ((name.as_str(), target), value))
}
#[inline]
#[must_use = "return value should be used"]
pub fn len(&self) -> usize {
self.values.len()
}
#[inline]
#[must_use = "return value should be used"]
pub fn is_empty(&self) -> bool {
self.values.is_empty()
}
#[inline]
#[must_use = "return value should be used"]
pub fn get(&self, name: &str, target: &AttributeTarget) -> Option<&AttributeValue> {
self.values
.iter()
.find(|((n, t), _)| n.as_str() == name && t == target)
.map(|(_, v)| v)
}
#[inline]
#[must_use = "return value should be used"]
pub fn get_network(&self, name: &str) -> Option<&AttributeValue> {
self.get(name, &AttributeTarget::Network)
}
#[inline]
#[must_use = "return value should be used"]
pub fn get_node(&self, node_name: &str, attr_name: &str) -> Option<&AttributeValue> {
self.values
.iter()
.find(|((n, t), _)| {
n.as_str() == attr_name
&& matches!(t, AttributeTarget::Node(name) if name.as_str() == node_name)
})
.map(|(_, v)| v)
}
#[inline]
#[must_use = "return value should be used"]
pub fn get_message(&self, message_id: u32, attr_name: &str) -> Option<&AttributeValue> {
self.values
.iter()
.find(|((n, t), _)| {
n.as_str() == attr_name
&& matches!(t, AttributeTarget::Message(id) if *id == message_id)
})
.map(|(_, v)| v)
}
#[inline]
#[must_use = "return value should be used"]
pub fn get_signal(
&self,
message_id: u32,
signal_name: &str,
attr_name: &str,
) -> Option<&AttributeValue> {
self.values
.iter()
.find(|((n, t), _)| {
n.as_str() == attr_name
&& matches!(t, AttributeTarget::Signal(msg_id, sig_name)
if *msg_id == message_id && sig_name.as_str() == signal_name)
})
.map(|(_, v)| v)
}
}