use linkrs_core::{Edge, Value};
pub(crate) fn read_edge_weight(edge: &Edge, name: &str) -> f64 {
if name == "ranking" {
let value = edge.ranking() as f64;
return clamp_weight(value);
}
let Some(raw) = edge.get_property(name) else {
return 1.0;
};
let value = match raw {
Value::Float(v) => f64::from(*v),
Value::Double(v) => *v,
Value::Int(v) => f64::from(*v),
Value::BigInt(v) => *v as f64,
Value::SmallInt(v) => f64::from(*v),
_ => return 1.0,
};
clamp_weight(value)
}
fn clamp_weight(value: f64) -> f64 {
if value.is_finite() && value > 0.0 {
value
} else {
0.0
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashMap;
use std::sync::Arc;
fn edge_with(props: HashMap<Arc<str>, Value>) -> Edge {
let vid =
|n| linkrs_core::types::storage_ids::VertexId::try_from_int64(n).expect("valid vid");
Edge {
src: vid(1),
dst: vid(2),
edge_type: "knows".to_string(),
ranking: 7,
props,
}
}
#[test]
fn missing_property_defaults_to_one() {
assert_eq!(read_edge_weight(&edge_with(HashMap::new()), "weight"), 1.0);
}
#[test]
fn numeric_properties_are_used() {
let mut props = HashMap::new();
props.insert(Arc::from("weight"), Value::Double(2.5));
props.insert(Arc::from("bad"), Value::Bool(true));
let edge = edge_with(props);
assert_eq!(read_edge_weight(&edge, "weight"), 2.5);
assert_eq!(read_edge_weight(&edge, "bad"), 1.0);
}
#[test]
fn every_numeric_kind_is_read() {
let mut props = HashMap::new();
props.insert(Arc::from("small"), Value::SmallInt(2));
props.insert(Arc::from("int"), Value::Int(3));
props.insert(Arc::from("big"), Value::BigInt(4));
props.insert(Arc::from("float"), Value::Float(5.5));
let edge = edge_with(props);
assert_eq!(read_edge_weight(&edge, "small"), 2.0);
assert_eq!(read_edge_weight(&edge, "int"), 3.0);
assert_eq!(read_edge_weight(&edge, "big"), 4.0);
assert_eq!(read_edge_weight(&edge, "float"), 5.5);
}
#[test]
fn negative_and_non_finite_clamp_to_zero() {
let mut props = HashMap::new();
props.insert(Arc::from("neg"), Value::Double(-3.0));
props.insert(Arc::from("inf"), Value::Double(f64::INFINITY));
let edge = edge_with(props);
assert_eq!(read_edge_weight(&edge, "neg"), 0.0);
assert_eq!(read_edge_weight(&edge, "inf"), 0.0);
}
#[test]
fn ranking_reads_the_rank_field() {
assert_eq!(read_edge_weight(&edge_with(HashMap::new()), "ranking"), 7.0);
}
}