mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-19 02:10:25 -05:00
Merge PR #885
This commit is contained in:
1 file changed
+22
-2
@@ -59,6 +59,12 @@ fn photo_arg(s: &Session, p: &Value, c: &str) -> crate::Result<PhotoId> {
|
||||
}
|
||||
}
|
||||
|
||||
// Catalog queries also run in the 32-bit web build. A narrowing cast wraps
|
||||
// an out-of-range offset to zero, returning the first page instead of no photos.
|
||||
fn pagination_usize(value: u64) -> usize {
|
||||
usize::try_from(value).unwrap_or(usize::MAX)
|
||||
}
|
||||
|
||||
pub fn specs() -> Vec<CommandSpec> {
|
||||
vec![
|
||||
cmd!(query "catalog.query", "Query Photos", [], None, "{filter?: Filter, sort?: Sort, offset?, limit?} — omit filter to list the current view", always, |s, p| {
|
||||
@@ -69,8 +75,8 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
} else {
|
||||
s.visible_cloned()
|
||||
};
|
||||
let off = p.get("offset").and_then(Value::as_u64).unwrap_or(0) as usize;
|
||||
let lim = p.get("limit").and_then(Value::as_u64).unwrap_or(200) as usize;
|
||||
let off = pagination_usize(p.get("offset").and_then(Value::as_u64).unwrap_or(0));
|
||||
let lim = pagination_usize(p.get("limit").and_then(Value::as_u64).unwrap_or(200));
|
||||
let items: Vec<Value> = ids.iter().skip(off).take(lim).filter_map(|id| s.catalog.photo(*id)).map(|p| photo_summary(p)).collect();
|
||||
Ok(json!({"total": ids.len(), "photos": items}))
|
||||
}),
|
||||
@@ -237,3 +243,17 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
}),
|
||||
]
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod pagination_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn offsets_and_limits_saturate_instead_of_wrapping_on_wasm() {
|
||||
assert_eq!(pagination_usize(0), 0);
|
||||
assert_eq!(pagination_usize(200), 200);
|
||||
assert_eq!(pagination_usize(u64::MAX), usize::MAX);
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
assert_eq!(pagination_usize(u64::from(u32::MAX) + 1), usize::MAX);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user