refactor(blahd): use NonZero/u32 for page length

This avoids platform-dependent `usize` in configuration and webapi.
This commit is contained in:
oxalica 2024-09-23 17:58:10 -04:00
parent 82f69eb96a
commit 1e8c16888c
2 changed files with 19 additions and 15 deletions

View file

@ -1,3 +1,4 @@
use std::num::NonZero;
use std::path::PathBuf; use std::path::PathBuf;
use anyhow::{ensure, Context}; use anyhow::{ensure, Context};
@ -283,7 +284,11 @@ pub trait TransactionOps {
.map_err(Into::into) .map_err(Into::into)
} }
fn list_public_rooms(&self, start_rid: Id, page_len: usize) -> Result<Vec<RoomMetadata>> { fn list_public_rooms(
&self,
start_rid: Id,
page_len: NonZero<u32>,
) -> Result<Vec<RoomMetadata>> {
// Attribute check must be written in the SQL literal so the query planer // Attribute check must be written in the SQL literal so the query planer
// can successfully pick the conditional index. // can successfully pick the conditional index.
const _: () = assert!(RoomAttrs::PUBLIC_READABLE.bits() == 1); const _: () = assert!(RoomAttrs::PUBLIC_READABLE.bits() == 1);
@ -312,7 +317,7 @@ pub trait TransactionOps {
&self, &self,
uid: i64, uid: i64,
start_rid: Id, start_rid: Id,
page_len: usize, page_len: NonZero<u32>,
) -> Result<Vec<RoomMetadata>> { ) -> Result<Vec<RoomMetadata>> {
prepare_cached_and_bind!( prepare_cached_and_bind!(
self.conn(), self.conn(),
@ -344,7 +349,7 @@ pub trait TransactionOps {
&self, &self,
uid: i64, uid: i64,
start_rid: Id, start_rid: Id,
page_len: usize, page_len: NonZero<u32>,
) -> Result<Vec<RoomMetadata>> { ) -> Result<Vec<RoomMetadata>> {
prepare_cached_and_bind!( prepare_cached_and_bind!(
self.conn(), self.conn(),
@ -385,7 +390,7 @@ pub trait TransactionOps {
rid: Id, rid: Id,
after_cid: Id, after_cid: Id,
before_cid: Id, before_cid: Id,
page_len: usize, page_len: NonZero<u32>,
) -> Result<Vec<WithMsgId<SignedChatMsg>>> { ) -> Result<Vec<WithMsgId<SignedChatMsg>>> {
prepare_cached_and_bind!( prepare_cached_and_bind!(
self.conn(), self.conn(),

View file

@ -1,4 +1,4 @@
use std::num::NonZeroUsize; use std::num::NonZero;
use std::sync::Arc; use std::sync::Arc;
use std::time::{Duration, SystemTime}; use std::time::{Duration, SystemTime};
@ -47,7 +47,7 @@ pub struct ServerConfig {
pub base_url: Url, pub base_url: Url,
#[serde_inline_default(1024.try_into().expect("not zero"))] #[serde_inline_default(1024.try_into().expect("not zero"))]
pub max_page_len: NonZeroUsize, pub max_page_len: NonZero<u32>,
#[serde_inline_default(4096)] // 4KiB #[serde_inline_default(4096)] // 4KiB
pub max_request_len: usize, pub max_request_len: usize,
@ -220,7 +220,7 @@ struct ListRoomParams {
// Workaround: serde(flatten) breaks deserialization // Workaround: serde(flatten) breaks deserialization
// See: https://github.com/nox/serde_urlencoded/issues/33 // See: https://github.com/nox/serde_urlencoded/issues/33
skip_token: Option<Id>, skip_token: Option<Id>,
top: Option<NonZeroUsize>, top: Option<NonZero<u32>>,
} }
#[derive(Debug, Clone, Copy, Deserialize)] #[derive(Debug, Clone, Copy, Deserialize)]
@ -260,8 +260,8 @@ async fn room_list(
} }
})?; })?;
let skip_token = let skip_token = (rooms.len() as u32 == page_len.get())
(rooms.len() == page_len).then(|| rooms.last().expect("page must not be empty").rid); .then(|| rooms.last().expect("page must not be empty").rid);
Ok(Json(RoomList { rooms, skip_token })) Ok(Json(RoomList { rooms, skip_token }))
} }
@ -354,18 +354,17 @@ struct Pagination {
/// A opaque token from previous response to fetch the next page. /// A opaque token from previous response to fetch the next page.
skip_token: Option<Id>, skip_token: Option<Id>,
/// Maximum page size. /// Maximum page size.
top: Option<NonZeroUsize>, top: Option<NonZero<u32>>,
/// Only return items before (excluding) this token. /// Only return items before (excluding) this token.
/// Useful for `room_msg_list` to pass `last_seen_cid` without over-fetching. /// Useful for `room_msg_list` to pass `last_seen_cid` without over-fetching.
until_token: Option<Id>, until_token: Option<Id>,
} }
impl Pagination { impl Pagination {
fn effective_page_len(&self, st: &AppState) -> usize { fn effective_page_len(&self, st: &AppState) -> NonZero<u32> {
self.top self.top
.unwrap_or(usize::MAX.try_into().expect("not zero")) .unwrap_or(u32::MAX.try_into().expect("not zero"))
.min(st.config.max_page_len) .min(st.config.max_page_len)
.get()
} }
} }
@ -544,8 +543,8 @@ fn query_room_msgs(
pagination.skip_token.unwrap_or(Id::MAX), pagination.skip_token.unwrap_or(Id::MAX),
page_len, page_len,
)?; )?;
let skip_token = let skip_token = (msgs.len() as u32 == page_len.get())
(msgs.len() == page_len).then(|| msgs.last().expect("page must not be empty").cid); .then(|| msgs.last().expect("page must not be empty").cid);
Ok((msgs, skip_token)) Ok((msgs, skip_token))
} }