use super::edge::EdgeIndex;
use crate::{
datatypes::{AttributeKey, Attributes},
from_marker::{FromMarker, IntoMarker},
ref_wrapper::RefWrapper,
};
use std::{collections::HashSet, fmt::Display};
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[repr(transparent)]
pub struct NodeIndex(AttributeKey);
impl<T: Into<AttributeKey>> From<T> for NodeIndex {
fn from(value: T) -> Self {
Self(value.into())
}
}
impl<T: IntoMarker<AttributeKey>> FromMarker<T> for NodeIndex {}
impl FromMarker<AttributeKey> for NodeIndex {}
impl Display for NodeIndex {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "NodeIndex({})", self.0)
}
}
pub type NodeIndexRef<'a> = RefWrapper<'a, NodeIndex>;
impl<'a, T: Into<NodeIndex> + IntoMarker<NodeIndex>> From<T> for NodeIndexRef<'a> {
fn from(value: T) -> Self {
Self::Owned(value.into())
}
}
#[derive(Debug, Clone)]
pub struct Node {
pub incoming_edges: HashSet<EdgeIndex>,
pub outgoing_edges: HashSet<EdgeIndex>,
pub attributes: Attributes,
}
impl Node {
pub(crate) fn new(attributes: Attributes) -> Self {
Node {
incoming_edges: HashSet::new(),
outgoing_edges: HashSet::new(),
attributes,
}
}
}
impl From<Attributes> for Node {
fn from(value: Attributes) -> Self {
Self::new(value)
}
}
pub type NodeTuple = (NodeIndex, Attributes);
pub trait IntoNodeTuple {
fn into_node_tuple(self) -> NodeTuple;
}
impl<N: Into<NodeIndex>, A: Into<Attributes>> IntoNodeTuple for (N, A) {
fn into_node_tuple(self) -> NodeTuple {
(self.0.into(), self.1.into())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_node_index_from() {
assert_eq!(
NodeIndex::from(false),
NodeIndex(AttributeKey::Boolean(false))
);
}
#[test]
fn test_node_index_display() {
assert_eq!(format!("{}", NodeIndex::from(false)), "NodeIndex(false)");
}
#[test]
fn test_node_index_ref_from() {
assert_eq!(
NodeIndexRef::from(false),
NodeIndexRef::Owned(NodeIndex::from(false))
);
}
#[test]
fn test_node_new() {
let attributes = Attributes::new();
let node = Node::new(attributes.clone());
assert_eq!(node.incoming_edges, HashSet::new());
assert_eq!(node.outgoing_edges, HashSet::new());
assert_eq!(node.attributes, attributes);
}
#[test]
fn test_node_from() {
let attributes = Attributes::new();
let node = Node::from(attributes.clone());
assert_eq!(node.incoming_edges, HashSet::new());
assert_eq!(node.outgoing_edges, HashSet::new());
assert_eq!(node.attributes, attributes);
}
#[test]
fn test_into_node_tuple() {
let index: NodeIndex = 0.into();
let attributes = Attributes::new();
let tuple = (index.clone(), attributes.clone()).into_node_tuple();
assert_eq!(tuple.0, index);
assert_eq!(tuple.1, attributes);
}
}