mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-24 10:09:01 -06:00
Fix smart album gte/lte rules missing equal f-number and focal length
Found while testing crates/catalog/src/rules.rs:673 (num_op), reached via Rule::matches at :956-957 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 5.5
parent
069e32f909
commit
c7cff2d9a7
@@ -670,6 +670,11 @@ fn number(v: &Value) -> Option<f64> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Widens an `f32` to the `f64` nearest its shortest decimal form (1.4f32 -> 1.4), so it compares equal to the value a user types.
|
||||
fn f32_as_decimal(v: f32) -> f64 {
|
||||
v.to_string().parse().unwrap_or(v as f64)
|
||||
}
|
||||
|
||||
fn num_op(op: &str, have: Option<f64>, value: &Value) -> bool {
|
||||
if op == "between" {
|
||||
let (a, b) = match value {
|
||||
@@ -953,8 +958,8 @@ impl Rule {
|
||||
"editDate" => date_op(op, p.edited.as_deref(), value),
|
||||
"shutterSpeed" => num_op(op, crate::parse_shutter_seconds(&m.shutter), &shutter_value(value)),
|
||||
"iso" => num_op(op, m.iso.map(|v| v as f64), value),
|
||||
"aperture" => num_op(op, m.aperture.map(|v| v as f64), value),
|
||||
"focalLength" => num_op(op, m.focal_mm.map(|v| v as f64), value),
|
||||
"aperture" => num_op(op, m.aperture.map(f32_as_decimal), value),
|
||||
"focalLength" => num_op(op, m.focal_mm.map(f32_as_decimal), value),
|
||||
"longEdge" | "shortEdge" => {
|
||||
let (w, h) = p.shown_size();
|
||||
num_op(op, Some(if field == "longEdge" { w.max(h) } else { w.min(h) }.round()), value)
|
||||
@@ -1129,6 +1134,25 @@ mod tests {
|
||||
serde_json::from_value(v).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn f32_boundary_values_match_gte_lte() {
|
||||
let cat = Catalog::new();
|
||||
let matches =
|
||||
|p: &Photo, field: &str, op: &str, value: f64| rs(json!({"rules": [{"field": field, "op": op, "value": value}]})).matches(p, &cat);
|
||||
for v in [1.4f32, 1.8, 2.8, 5.6, 0.95] {
|
||||
let mut p = photo(1);
|
||||
p.meta.aperture = Some(v);
|
||||
p.meta.focal_mm = Some(v);
|
||||
let w = v.to_string().parse::<f64>().unwrap();
|
||||
for field in ["aperture", "focalLength"] {
|
||||
assert!(matches(&p, field, "gte", w), "{field} gte {w}");
|
||||
assert!(matches(&p, field, "lte", w), "{field} lte {w}");
|
||||
assert!(!matches(&p, field, "gt", w), "{field} gt {w}");
|
||||
assert!(!matches(&p, field, "lt", w), "{field} lt {w}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fields_ops_and_groups() {
|
||||
let cat = Catalog::new();
|
||||
|
||||
Reference in New Issue
Block a user