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
use super::math_round_div::round_div; ← from math.round-div ^1.0.0 · built alongside by fune
use super::money_amount::{money, money_from_value, money_to_value, Money}; ← from money.amount ^1.0.0 · built alongside by fune
/// Snap a price to the points k x step - ending.
///
/// Shifting by `ending` turns every point into a multiple of `step`, so the
/// whole policy is one integer division with the right rounding mode.
///
/// # Panics
/// Panics on a step below 1, an ending outside 0..step, a negative price,
/// `down` below the first point, or an unknown direction.
pub fn round_price(price: &Money, step: i64, ending: i64, direction: &str) -> Money {
if step < 1 {
panic!("step must be 1 or more, received {}", step);
}
if ending < 0 || ending >= step {
panic!("ending must be from 0 to step - 1, received {}", ending);
}
if price.minor < 0 {
panic!("price must not be negative, received {}", price.minor);
}
let shifted = price.minor + ending;
let point = match direction {
"up" => round_div(shifted, step, "up") * step - ending,
"down" => {
let point = round_div(shifted, step, "down") * step - ending;
if point < 0 {
panic!("no price point at or below {}", price.minor);
}
point
}
"nearest" => {
let point = round_div(shifted, step, "half-up") * step - ending;
// Below the first point the only candidate is above.
if point < 0 {
step - ending
} else {
point
}
}
other => panic!("unknown direction \"{}\"", other),
};
money(point, &price.currency)
}
pub fn fune_vector(args: &[Value]) -> Value {
money_to_value(&round_price(
&money_from_value(&args[0]),
args[1].as_i64(),
args[2].as_i64(),
args[3].as_str(),
))
}