use std::cmp::{Ord, Ordering, PartialOrd};
use std::fmt;
use std::fmt::{Debug, Display};
use std::hash::{Hash, Hasher};
#[derive(Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Edge<T, A>
where
T: PartialOrd + Send,
{
pub u: T,
pub v: T,
pub attributes: Option<A>,
pub weight: f64,
}
impl<T, A> Edge<T, A>
where
T: Eq + Clone + PartialOrd + Ord + Hash + Send + Sync + Display,
A: Clone,
{
pub fn new(u: T, v: T) -> Edge<T, A> {
Edge {
u,
v,
attributes: None,
weight: f64::NAN,
}
}
pub fn ordered(self: Edge<T, A>) -> Edge<T, A> {
match self.u > self.v {
true => self.reversed(),
false => self,
}
}
pub fn reversed(self: Edge<T, A>) -> Edge<T, A> {
Edge {
u: self.v,
v: self.u,
..self
}
}
pub fn with_weight(u: T, v: T, weight: f64) -> Edge<T, A> {
Edge {
u,
v,
attributes: None,
weight,
}
}
}
impl<T: PartialEq + PartialOrd + Send + Sync, A> PartialEq for Edge<T, A> {
fn eq(&self, other: &Self) -> bool {
self.u == other.u && self.v == other.v
}
}
impl<T: Eq + PartialOrd + Send + Sync, A> Eq for Edge<T, A> {}
impl<T: Debug + PartialOrd + Send + Sync, A> fmt::Debug for Edge<T, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Node")
.field("u", &self.u)
.field("v", &self.v)
.finish()
}
}
impl<T: Display + PartialOrd + Send + Sync, A> fmt::Display for Edge<T, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({}, {})", self.u, self.v)
}
}
impl<T: Hash + PartialOrd + Send + Sync, A> Hash for Edge<T, A> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.u.hash(state);
self.v.hash(state);
}
}
impl<T: Eq + PartialEq + PartialOrd + Send + Sync, A> PartialOrd for Edge<T, A> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<T: Eq + PartialOrd + Send + Sync, A> Ord for Edge<T, A> {
fn cmp(&self, other: &Self) -> Ordering {
let u_cmp = self.u.partial_cmp(&other.u).unwrap();
match u_cmp {
Ordering::Equal => self.v.partial_cmp(&other.v).unwrap(),
Ordering::Greater => u_cmp,
Ordering::Less => u_cmp,
}
}
}