api_params.rs (3436B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2024-2025 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it under the 6 terms of the GNU Affero General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 12 13 You should have received a copy of the GNU Affero General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 17 use serde::Deserialize; 18 use serde_with::{DisplayFromStr, serde_as}; 19 20 use crate::{api_wire::TransferState, types::payto::PaytoURI}; 21 22 #[derive(Debug, thiserror::Error)] 23 #[error("Param '{param}' {reason}")] 24 pub struct ParamsErr { 25 pub param: &'static str, 26 pub reason: String, 27 } 28 29 pub fn param_err(param: &'static str, reason: String) -> ParamsErr { 30 ParamsErr { param, reason } 31 } 32 33 #[serde_as] 34 #[derive(Debug, Clone, Deserialize)] 35 /// <https://docs.taler.net/core/api-common.html#row-id-pagination> 36 pub struct PageParams { 37 #[serde_as(as = "Option<DisplayFromStr>")] 38 #[serde(alias = "delta")] 39 pub limit: Option<i64>, 40 #[serde_as(as = "Option<DisplayFromStr>")] 41 #[serde(alias = "start")] 42 pub offset: Option<i64>, 43 } 44 45 impl PageParams { 46 pub fn check(self, max_page_size: i64) -> Result<Page, ParamsErr> { 47 let limit = self.limit.unwrap_or(-20); 48 if limit == 0 { 49 return Err(param_err("limit", format!("must be non-zero got {limit}"))); 50 } else if limit > max_page_size { 51 return Err(param_err( 52 "limit", 53 format!("must be <= {max_page_size} for {limit}"), 54 )); 55 } 56 if let Some(offset) = self.offset 57 && offset < 0 58 { 59 return Err(param_err( 60 "offset", 61 format!("must be positive got {offset}"), 62 )); 63 } 64 65 Ok(Page { 66 limit, 67 offset: self.offset, 68 }) 69 } 70 } 71 72 #[derive(Debug)] 73 pub struct Page { 74 pub limit: i64, 75 pub offset: Option<i64>, 76 } 77 78 impl Default for Page { 79 fn default() -> Self { 80 Self { 81 limit: 20, 82 offset: None, 83 } 84 } 85 } 86 87 impl Page { 88 pub fn backward(&self) -> bool { 89 self.limit < 0 90 } 91 } 92 93 #[derive(Debug, Clone, Deserialize)] 94 /// <https://docs.taler.net/core/api-common.html#long-polling> 95 pub struct HistoryParams { 96 #[serde(flatten)] 97 pub pagination: PageParams, 98 #[serde(alias = "long_poll_ms")] 99 pub timeout_ms: Option<u64>, 100 } 101 102 impl HistoryParams { 103 pub fn check(self, max_page_size: i64, max_timeout_ms: u64) -> Result<History, ParamsErr> { 104 let timeout_ms = self.timeout_ms.map(|it| it.min(max_timeout_ms)); 105 Ok(History { 106 page: self.pagination.check(max_page_size)?, 107 timeout_ms, 108 }) 109 } 110 } 111 112 #[derive(Debug, Default)] 113 pub struct History { 114 pub page: Page, 115 pub timeout_ms: Option<u64>, 116 } 117 118 #[derive(Debug, Clone, Deserialize)] 119 pub struct TransferParams { 120 #[serde(flatten)] 121 pub pagination: PageParams, 122 pub status: Option<TransferState>, 123 } 124 125 #[derive(Debug, Clone, Deserialize)] 126 pub struct AccountParams { 127 pub account: PaytoURI, 128 }