Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
use super::funejson::Value; ← the fune runtime: the JSON value the test vectors use; fune build keeps it only where a signature takes one
/// The tick step for about `count` ticks: 1, 2 or 5 times a power of ten, as
/// d3-array's tickIncrement chooses it, found without log10 and returned as one
/// correctly rounded division so 0.2 is exactly the double 0.2.
///
/// # Panics
/// Panics if start or stop is not finite or `count` is less than 1.
pub fn tick_step(start: f64, stop: f64, count: i64) -> f64 {
let (mul, div) = tick_spec(start, stop, count);
mul / div
}
// Exported for nice_ticks, which needs the step as a multiplier or a divisor.
/// The step as (multiplier, divisor), one of which is 1; (0, 1) when start
/// equals stop.
pub fn tick_spec(start: f64, stop: f64, count: i64) -> (f64, f64) {
if !start.is_finite() || !stop.is_finite() {
panic!("start and stop must be finite numbers; got {} and {}", start, stop);
}
if count < 1 {
panic!("count must be a whole number of at least 1, got {}", count);
}
let raw = (stop - start).abs() / count as f64;
if raw == 0.0 {
return (0.0, 1.0);
}
if raw >= 1.0 {
let mut power = 1.0;
while power * 10.0 <= raw {
power *= 10.0;
}
return (nice_factor(raw / power) * power, 1.0);
}
let mut inverse = 1.0;
while raw * inverse < 1.0 {
inverse *= 10.0;
}
let factor = nice_factor(raw * inverse);
if factor == inverse {
(1.0, 1.0)
} else {
(1.0, inverse / factor)
}
}
fn nice_factor(error: f64) -> f64 {
if error >= 50f64.sqrt() {
10.0
} else if error >= 10f64.sqrt() {
5.0
} else if error >= 2f64.sqrt() {
2.0
} else {
1.0
}
}
pub fn fune_vector(args: &[Value]) -> Value {
// Refuse what the typed signature cannot hold, with the wording TypeScript
// and Python use, rather than let the conversion below quietly change it.
if matches!(args[2], Value::Float(f) if f.fract() != 0.0) {
panic!("count must be a whole number of at least 1");
}
Value::Float(tick_step(args[0].as_f64(), args[1].as_f64(), args[2].as_i64()))
}