use std::collections::HashMap;
use std::fmt::Debug;
pub type NodeId = usize;
pub type EdgeId = usize;
pub trait EdgeType: Clone + Debug {
fn as_string(&self) -> String;
}
#[derive(Debug)]
pub struct HEdge<W, E: EdgeType> {
pub id: EdgeId,
pub from: NodeId,
pub to: NodeId,
pub weight: W,
pub data: E,
pub attributes: HashMap<String, String>,
}
impl<W, E: EdgeType> HEdge<W, E> {
pub fn new(id: EdgeId, from: NodeId, to: NodeId, weight: W, data: E) -> Self {
Self {
id,
from,
to,
weight,
data,
attributes: HashMap::new(), }
}
}
impl EdgeType for String {
fn as_string(&self) -> String {
self.clone()
}
}
impl EdgeType for u32 {
fn as_string(&self) -> String {
self.to_string()
}
}
impl EdgeType for f64 {
fn as_string(&self) -> String {
self.to_string()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(Clone, Debug)]
struct TestEdge(String);
impl EdgeType for TestEdge {
fn as_string(&self) -> String {
self.0.clone()
}
}
#[test]
fn test_edge_creation() {
let edge: HEdge<f64, TestEdge> = HEdge::new(0, 1, 2, 3.5, TestEdge("test".to_string()));
assert_eq!(edge.id, 0);
assert_eq!(edge.from, 1);
assert_eq!(edge.to, 2);
assert_eq!(edge.weight, 3.5);
assert_eq!(edge.data.as_string(), "test");
assert!(edge.attributes.is_empty());
}
#[test]
fn test_edge_attributes() {
let mut edge: HEdge<u32, TestEdge> =
HEdge::new(1, 0, 1, 10, TestEdge("connection".to_string()));
edge.attributes
.insert("type".to_string(), "road".to_string());
edge.attributes
.insert("length".to_string(), "100".to_string());
assert_eq!(edge.attributes.get("type"), Some(&"road".to_string()));
assert_eq!(edge.attributes.get("length"), Some(&"100".to_string()));
assert_eq!(edge.attributes.len(), 2);
edge.attributes
.insert("type".to_string(), "bridge".to_string());
assert_eq!(edge.attributes.get("type"), Some(&"bridge".to_string()));
}
#[test]
fn test_edge_type_primitives() {
let string_edge: HEdge<i32, String> = HEdge::new(0, 1, 2, 5, "relation".to_string());
assert_eq!(string_edge.data.as_string(), "relation");
let u32_edge: HEdge<f64, u32> = HEdge::new(1, 0, 1, 2.5, 42);
assert_eq!(u32_edge.data.as_string(), "42");
let f64_edge: HEdge<i64, f64> = HEdge::new(2, 2, 3, 10, 3.14);
assert_eq!(f64_edge.data.as_string(), "3.14");
}
#[test]
fn test_custom_edge_type() {
#[derive(Clone, Debug)]
struct CustomEdge {
label: String,
priority: i32,
}
impl EdgeType for CustomEdge {
fn as_string(&self) -> String {
format!("{}:{}", self.label, self.priority)
}
}
let edge: HEdge<f64, CustomEdge> = HEdge::new(
0,
1,
2,
1.0,
CustomEdge {
label: "path".to_string(),
priority: 5,
},
);
assert_eq!(edge.data.as_string(), "path:5");
assert_eq!(edge.from, 1);
assert_eq!(edge.to, 2);
assert_eq!(edge.weight, 1.0);
}
}