use gunnar_proto::usage_batch_server::UsageBatch;
use gunnar_proto::{GrantLevel, ReadManyUsageRequest, ReadManyUsageResponse};
use tonic::{Request, Response, Status};
use crate::auth::Access;
use crate::service::UsageBatchService;
pub const DEFAULT_PAGE_SIZE: u32 = 500;
pub const MAX_PAGE_SIZE: u32 = 5_000;
pub fn page_size(asked: u32) -> usize {
match asked {
0 => DEFAULT_PAGE_SIZE as usize,
n => n.min(MAX_PAGE_SIZE) as usize,
}
}
#[tonic::async_trait]
impl UsageBatch for UsageBatchService {
async fn read_many(
&self,
request: Request<ReadManyUsageRequest>,
) -> Result<Response<ReadManyUsageResponse>, Status> {
let caller = self.ctx.authorize(
&request,
Access::Server,
GrantLevel::Read,
"UsageBatch.ReadMany",
)?;
let request = request.into_inner();
let mut page = self.ctx.control.usage_page(
&request.page_token,
page_size(request.page_size),
&request.changed_since,
)?;
page.usages = self.ctx.retain_unshielded(&caller, page.usages, |row| {
row.namespace.contains('/').then(|| row.namespace.clone())
})?;
Ok(Response::new(page))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_page_size_defaults_and_is_clamped() {
assert_eq!(page_size(0), 500);
assert_eq!(page_size(7), 7);
assert_eq!(page_size(1_000_000), 5_000);
}
}