use std::collections::HashMap;
pub use crate::core::view::{EdgeId, NodeId};
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Node<W, N> {
pub data: N,
pub neighbors: Vec<(NodeId, EdgeId, W)>,
pub attributes: HashMap<String, String>,
}
impl<W, N: Default> Default for Node<W, N> {
fn default() -> Self {
Self {
data: N::default(),
neighbors: Vec::new(),
attributes: HashMap::new(),
}
}
}
impl<W, N> Node<W, N> {
pub fn new(data: N) -> Self {
Node {
data,
neighbors: Vec::new(),
attributes: HashMap::new(),
}
}
pub fn add_neighbor(&mut self, neighbor_id: NodeId, edge_id: EdgeId, weight: W) {
self.neighbors.push((neighbor_id, edge_id, weight));
}
pub fn neighbor_ids(&self) -> impl Iterator<Item = NodeId> + '_ {
self.neighbors.iter().map(|&(id, _, _)| id)
}
pub fn degree(&self) -> usize {
self.neighbors.len()
}
pub fn get_attribute(&self, key: &str) -> Option<&String> {
self.attributes.get(key)
}
pub fn set_attribute(&mut self, key: String, value: String) -> Option<String> {
self.attributes.insert(key, value)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::view::{EdgeId, NodeId};
#[test]
fn test_node_creation() {
let node = Node::<i32, &str>::new("Test");
assert_eq!(node.data, "Test");
assert!(node.neighbors.is_empty());
assert!(node.attributes.is_empty());
}
#[test]
fn test_default_node() {
let node: Node<f64, String> = Node::default();
assert_eq!(node.data, String::new());
assert!(node.neighbors.is_empty());
assert!(node.attributes.is_empty());
}
#[test]
fn test_add_neighbor() {
let mut node = Node::<u32, i32>::new(1);
node.add_neighbor(NodeId::from_index(2), EdgeId::from_index(0), 10);
node.add_neighbor(NodeId::from_index(3), EdgeId::from_index(1), 20);
assert_eq!(
node.neighbors,
vec![
(NodeId::from_index(2), EdgeId::from_index(0), 10),
(NodeId::from_index(3), EdgeId::from_index(1), 20)
]
);
assert_eq!(node.degree(), 2);
assert_eq!(
node.neighbor_ids().collect::<Vec<_>>(),
vec![NodeId::from_index(2), NodeId::from_index(3)]
);
}
#[test]
fn test_attributes() {
let mut node = Node::<f32, &str>::new("Node");
node.set_attribute("size".to_string(), "large".to_string());
assert_eq!(node.get_attribute("size"), Some(&"large".to_string()));
assert_eq!(node.get_attribute("color"), None);
}
}