mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-14 19:26:56 -04:00
Plug-ins: whole-number parameters keep their exact value and stay in range
This commit is contained in:
1 parent
f79858c12c
commit
aecf88c1c1
1 file changed
+33
-2
@@ -203,8 +203,16 @@ impl Manifest {
|
||||
let resolved = match spec {
|
||||
ParamSpec::Number { min, max, .. } => json!(v.as_f64().filter(|f| f.is_finite()).ok_or_else(|| wrong("a number"))?.clamp(*min, *max)),
|
||||
ParamSpec::Int { min, max, .. } => {
|
||||
let f = v.as_f64().filter(|f| f.is_finite()).ok_or_else(|| wrong("a number"))?;
|
||||
json!((f.round().clamp(*min as f64, *max as f64)) as i64)
|
||||
// Keep JSON integers exact: f64 cannot represent every i64 or its bounds.
|
||||
let value = if let Some(i) = v.as_i64() {
|
||||
i.clamp(*min, *max)
|
||||
} else if let Some(i) = v.as_u64() {
|
||||
i128::from(i).clamp(i128::from(*min), i128::from(*max)) as i64
|
||||
} else {
|
||||
let f = v.as_f64().filter(|f| f.is_finite()).ok_or_else(|| wrong("a number"))?;
|
||||
(f.round() as i64).clamp(*min, *max)
|
||||
};
|
||||
json!(value)
|
||||
}
|
||||
ParamSpec::Bool { .. } => json!(v.as_bool().ok_or_else(|| wrong("true or false"))?),
|
||||
ParamSpec::Choice { options, .. } => {
|
||||
@@ -303,6 +311,29 @@ mod tests {
|
||||
assert!(m.resolve_params(&Value::Null).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn integer_parameters_preserve_precision_and_exact_bounds() {
|
||||
let m = Manifest::parse(
|
||||
br#"{"id":"org.example.generative","name":"Generative Pattern","kind":"filter",
|
||||
"params":{"seed":{"type":"int","min":-9007199254740995,"max":9007199254740995}}}"#,
|
||||
)
|
||||
.unwrap();
|
||||
for (given, expected) in [
|
||||
(json!(9007199254740992_i64), 9007199254740992_i64),
|
||||
(json!(9007199254740993_i64), 9007199254740993_i64),
|
||||
(json!(-9007199254740993_i64), -9007199254740993_i64),
|
||||
(json!(i64::MAX), 9007199254740995_i64),
|
||||
(json!(i64::MIN), -9007199254740995_i64),
|
||||
(json!(u64::MAX), 9007199254740995_i64),
|
||||
(json!(1e30), 9007199254740995_i64),
|
||||
(json!(-1e30), -9007199254740995_i64),
|
||||
(json!(3.6), 4_i64),
|
||||
] {
|
||||
let resolved = m.resolve_params(&json!({"seed": given})).unwrap();
|
||||
assert_eq!(resolved["seed"], json!(expected), "input: {given}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_bad_manifests() {
|
||||
for bad in [
|
||||
|
||||
Reference in new issue
Block a user