use code_ranker_plugin_api::{attrs::AttrValue, node::Node};
pub fn round_sig3(x: f64) -> f64 {
if !x.is_finite() || x == 0.0 {
return 0.0;
}
let abs = x.abs();
let sign = if x < 0.0 { -1.0 } else { 1.0 };
let truncated = if abs >= 1.0 {
(abs * 1000.0).floor() / 1000.0
} else {
let d = abs.log10().floor() as i32;
let factor = 10f64.powi(2 - d);
(abs * factor).floor() / factor
};
truncated * sign
}
pub fn num_attr(x: f64) -> AttrValue {
let r = round_sig3(x);
if r.fract() == 0.0 && r.abs() < i64::MAX as f64 {
AttrValue::Int(r as i64)
} else {
AttrValue::Float(r)
}
}
pub(crate) fn attr_f64(node: &Node, key: &str) -> Option<f64> {
match node.attrs.get(key) {
Some(AttrValue::Int(i)) => Some(*i as f64),
Some(AttrValue::Float(f)) => Some(*f),
_ => None,
}
}
pub(crate) fn is_external(node: &Node) -> bool {
node.kind == "external" || matches!(node.attrs.get("external"), Some(AttrValue::Bool(true)))
}