mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-14 19:26:56 -04:00
Plug-ins: numeric defaults stay in their declared range
This commit is contained in:
1 parent
847730bf8b
commit
08c8c11798
2 files changed
+27
-6
No files matched your search
@@ -67,11 +67,11 @@ fn int_max() -> i64 {
|
||||
}
|
||||
|
||||
impl ParamSpec {
|
||||
/// The value a parameter takes when it isn't given.
|
||||
/// The value a parameter takes when it isn't given (numeric defaults clamped into range).
|
||||
pub fn default_value(&self) -> Value {
|
||||
match self {
|
||||
ParamSpec::Number { default, .. } => json!(default),
|
||||
ParamSpec::Int { default, .. } => json!(default),
|
||||
ParamSpec::Number { min, max, default } => json!(default.clamp(*min, *max)),
|
||||
ParamSpec::Int { min, max, default } => json!((*default).clamp(*min, *max)),
|
||||
ParamSpec::Bool { default } => json!(default),
|
||||
ParamSpec::Choice { options, default } => json!(default.clone().or_else(|| options.first().cloned()).unwrap_or_default()),
|
||||
}
|
||||
@@ -167,8 +167,8 @@ impl Manifest {
|
||||
.params
|
||||
.iter()
|
||||
.map(|(k, spec)| match spec {
|
||||
ParamSpec::Number { min, max, default } => format!("{k}: {min}..{max} ({default})"),
|
||||
ParamSpec::Int { min, max, default } => format!("{k}: int {min}..{max} ({default})"),
|
||||
ParamSpec::Number { min, max, default } => format!("{k}: {min}..{max} ({})", default.clamp(*min, *max)),
|
||||
ParamSpec::Int { min, max, default } => format!("{k}: int {min}..{max} ({})", (*default).clamp(*min, *max)),
|
||||
ParamSpec::Bool { default } => format!("{k}: bool ({default})"),
|
||||
ParamSpec::Choice { options, .. } => {
|
||||
let opts: Vec<String> = options.iter().map(|o| format!("{o:?}")).collect();
|
||||
@@ -335,6 +335,26 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn numeric_defaults_stay_in_the_declared_range() {
|
||||
let m = Manifest::parse(
|
||||
br#"{"id":"org.example.defaults","name":"Defaults","kind":"filter",
|
||||
"params":{"count":{"type":"int","min":1,"max":10},
|
||||
"seed":{"type":"int","min":-9007199254740995,"max":-9007199254740993,"default":0},
|
||||
"amount":{"type":"number","min":0,"max":100,"default":500}}}"#,
|
||||
)
|
||||
.unwrap();
|
||||
let expected = json!({"count": 1, "seed": -9007199254740993_i64, "amount": 100.0});
|
||||
assert_eq!(Value::Object(m.defaults()), expected);
|
||||
assert_eq!(
|
||||
m.params_doc(),
|
||||
"{count: int 1..10 (1), seed: int -9007199254740995..-9007199254740993 (-9007199254740993), amount: 0..100 (100)}"
|
||||
);
|
||||
for given in [Value::Null, json!({}), json!({"count": null, "seed": null, "amount": null})] {
|
||||
assert_eq!(Value::Object(m.resolve_params(&given).unwrap()), expected);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_bad_manifests() {
|
||||
for bad in [
|
||||
|
||||
+2
-1
@@ -111,7 +111,8 @@ pointers are offsets into the module's memory.
|
||||
- `name`: the menu label (1–64 printable characters). `kind`: `"filter"` (object filter) or `"effect"` (live effect).
|
||||
- `params`: in dialog order. Names are `[A-Za-z0-9_]`, not starting with `_`, and not `id`, `ids`, `params` or
|
||||
`preview`. The host validates the user's values before calling: missing values take the default, numbers are
|
||||
clamped to `min..max` (ints rounded), a wrong type or an unknown choice is an error.
|
||||
clamped to `min..max` (ints rounded), a wrong type or an unknown choice is an error. Numeric defaults
|
||||
are also clamped to their range, including the implicit zero default of an `int` parameter.
|
||||
|
||||
### Input
|
||||
|
||||
|
||||
Reference in new issue
Block a user