taler-rust

GNU Taler code in Rust. Largely core banking integrations.
Log | Files | Refs | Submodules | README | LICENSE

commit dae0531936b449deef1242dfcbcea994de9e3fe2
parent df153ed4bc1b3bd3786db54158f82130adcb413f
Author: Antoine A <>
Date:   Thu, 26 Mar 2026 16:02:35 +0100

common: reduce memory usage and allocations

Diffstat:
Mtaler-cyclos/src/cyclos_api/types.rs | 28++++++++++++++--------------
Mtaler-cyclos/src/db.rs | 18+++++++++---------
Mtaler-cyclos/tests/api.rs | 4++--
Mtaler-magnet-bank/src/db.rs | 26+++++++++++++-------------
Mtaler-magnet-bank/src/magnet_api/types.rs | 53+++++++++++++++++++++++++++--------------------------
Mtaler-magnet-bank/tests/api.rs | 4++--
6 files changed, 67 insertions(+), 66 deletions(-)

diff --git a/taler-cyclos/src/cyclos_api/types.rs b/taler-cyclos/src/cyclos_api/types.rs @@ -37,8 +37,8 @@ pub enum OrderBy { #[serde(rename_all = "camelCase")] pub struct Type { pub id: CyclosId, - pub internal_name: Option<String>, - pub name: String, + pub internal_name: Option<CompactString>, + pub name: CompactString, } #[derive(Debug, Deserialize, Clone)] @@ -47,7 +47,7 @@ pub struct Currency { #[serde(flatten)] pub ty: Type, pub decimal_digits: u8, - pub symbol: String, + pub symbol: CompactString, } #[derive(Debug, Deserialize, Clone)] @@ -70,7 +70,7 @@ pub struct Account { #[serde(rename_all = "camelCase")] pub struct User { pub id: CyclosId, - pub name: String, + pub name: CompactString, } impl User { @@ -115,7 +115,7 @@ pub struct Pagination<T> { pub struct HistoryItem { pub id: CyclosId, pub date: Timestamp, - pub amount: String, + pub amount: CompactString, #[serde(rename = "type")] pub ty: Type, pub description: Option<String>, @@ -215,7 +215,7 @@ pub enum InvalidDeviceConfirmation { #[serde(rename_all = "camelCase")] pub struct UserInfo { pub id: CyclosId, - pub display: String, + pub display: CompactString, } #[derive(Debug, serde::Deserialize)] @@ -246,11 +246,11 @@ pub struct Notification { #[derive(Debug, serde::Deserialize)] #[serde(rename_all = "camelCase")] pub struct DataForUi { - pub cyclos_version: String, - pub cyclos_revision: String, + pub cyclos_version: CompactString, + pub cyclos_revision: CompactString, pub root_url: Url, pub api_url: Url, - pub application_name: String, + pub application_name: CompactString, } #[derive(Debug, serde::Deserialize)] @@ -403,8 +403,8 @@ pub enum UnavailableError { #[error("{entity_type} {key}")] /// Error codes for 404 Not Found pub struct NotFoundError { - pub entity_type: String, - pub key: String, + pub entity_type: CompactString, + pub key: CompactString, } #[derive(Debug, serde::Deserialize, thiserror::Error)] @@ -460,9 +460,9 @@ pub enum InputError { #[serde(rename_all = "camelCase")] MaxItems { max_items: usize }, #[error("missingParameter {name} - Missing a required request parameter")] - MissingParameter { name: String }, + MissingParameter { name: CompactString }, #[error("queryParse {value} - A full-text query keywords contained an invalid text")] - QueryParse { value: String }, + QueryParse { value: CompactString }, #[error( "validation {general_errors:?} {property_errors:?} - One or more of the fields sent contains invalid values" )] @@ -471,7 +471,7 @@ pub enum InputError { #[serde(default)] general_errors: Vec<String>, #[serde(default)] - properties: Vec<String>, + properties: Vec<CompactString>, #[serde(default)] property_errors: BTreeMap<String, Vec<String>>, }, diff --git a/taler-cyclos/src/db.rs b/taler-cyclos/src/db.rs @@ -95,7 +95,7 @@ pub struct TxIn { pub amount: Decimal, pub subject: String, pub debtor_id: i64, - pub debtor_name: String, + pub debtor_name: CompactString, pub valued_at: Timestamp, } @@ -128,7 +128,7 @@ pub struct TxOut { pub amount: Decimal, pub subject: String, pub creditor_id: i64, - pub creditor_name: String, + pub creditor_name: CompactString, pub valued_at: Timestamp, } @@ -160,7 +160,7 @@ pub struct Initiated { pub amount: Decimal, pub subject: String, pub creditor_id: i64, - pub creditor_name: String, + pub creditor_name: CompactString, } impl Display for Initiated { @@ -990,7 +990,7 @@ mod test { amount: decimal("10"), subject: "subject".to_owned(), debtor_id: 31000163100000000, - debtor_name: "Name".to_string(), + debtor_name: "Name".into(), valued_at: now, }; // Insert @@ -1190,7 +1190,7 @@ mod test { amount: decimal("10"), subject: "subject".to_owned(), creditor_id: 31000163100000000, - creditor_name: "Name".to_string(), + creditor_name: "Name".into(), valued_at: now, }; assert!(matches!( @@ -1439,7 +1439,7 @@ mod test { amount, subject: "subject".to_owned(), debtor_id: 31000163100000000, - debtor_name: "Name".to_string(), + debtor_name: "Name".into(), valued_at: now }, 22, @@ -1463,7 +1463,7 @@ mod test { amount, subject: "subject".to_owned(), debtor_id: 31000163100000000, - debtor_name: "Name".to_string(), + debtor_name: "Name".into(), valued_at: now }, 22, @@ -1488,7 +1488,7 @@ mod test { amount, subject: "subject".to_owned(), debtor_id: 31000163100000000, - debtor_name: "Name".to_string(), + debtor_name: "Name".into(), valued_at: now }, 23, @@ -1582,7 +1582,7 @@ mod test { amount: decimal("2"), subject: "".to_string(), creditor_id: 31000163100000000, - creditor_name: "Name".to_string(), + creditor_name: "Name".into(), valued_at: Timestamp::now(), }, &TxOutKind::Simple, diff --git a/taler-cyclos/tests/api.rs b/taler-cyclos/tests/api.rs @@ -125,7 +125,7 @@ async fn outgoing_history() { amount: decimal("10"), subject: "subject".to_owned(), creditor_id: 31000163100000000, - creditor_name: "Name".to_string(), + creditor_name: "Name".into(), valued_at: Timestamp::now(), }, &TxOutKind::Talerable(OutgoingSubject::rand()), @@ -189,7 +189,7 @@ pub async fn test_in(pool: &PgPool, key: EddsaPublicKey) { amount: decimal("12"), subject: String::new(), debtor_id: rand::random_range(10..10000), - debtor_name: "Name".to_owned(), + debtor_name: "Name".into(), valued_at: Timestamp::now(), }; let mut db = pool.acquire().await.unwrap(); diff --git a/taler-magnet-bank/src/db.rs b/taler-magnet-bank/src/db.rs @@ -89,7 +89,7 @@ pub async fn notification_listener( pub struct TxIn { pub code: u64, pub amount: Amount, - pub subject: String, + pub subject: Box<str>, pub debtor: FullHuPayto, pub value_date: Date, pub status: TxStatus, @@ -118,7 +118,7 @@ impl Display for TxIn { pub struct TxOut { pub code: u64, pub amount: Amount, - pub subject: String, + pub subject: Box<str>, pub creditor: FullHuPayto, pub value_date: Date, pub status: TxStatus, @@ -147,7 +147,7 @@ impl Display for TxOut { pub struct Initiated { pub id: u64, pub amount: Amount, - pub subject: String, + pub subject: Box<str>, pub creditor: FullHuPayto, } @@ -950,7 +950,7 @@ mod test { let tx = TxIn { code, amount: amount("EUR:10"), - subject: "subject".to_owned(), + subject: "subject".into(), debtor: magnet_payto( "payto://iban/HU30162000031000163100000000?receiver-name=name", ), @@ -1153,7 +1153,7 @@ mod test { let tx = TxOut { code, amount: amount("HUF:10"), - subject: "subject".to_owned(), + subject: "subject".into(), creditor: magnet_payto( "payto://iban/HU30162000031000163100000000?receiver-name=name", ), @@ -1330,7 +1330,7 @@ mod test { let tx = TxIn { code: 12, amount: amount("HUF:11"), - subject: "malformed transaction".to_owned(), + subject: "malformed transaction".into(), debtor: payto, value_date: Zoned::now().date(), status: TxStatus::Completed, @@ -1484,7 +1484,7 @@ mod test { &TxIn { code: 13, amount: amount.clone(), - subject: "subject".to_owned(), + subject: "subject".into(), debtor: payto.clone(), value_date: date, status: TxStatus::Completed @@ -1509,7 +1509,7 @@ mod test { &TxIn { code: 12, amount: amount.clone(), - subject: "subject".to_owned(), + subject: "subject".into(), debtor: payto.clone(), value_date: date, status: TxStatus::Completed @@ -1533,7 +1533,7 @@ mod test { &TxIn { code: 12, amount: amount.clone(), - subject: "subject".to_owned(), + subject: "subject".into(), debtor: payto.clone(), value_date: date, status: TxStatus::Completed @@ -1558,7 +1558,7 @@ mod test { &TxIn { code: 13, amount: amount.clone(), - subject: "subject".to_owned(), + subject: "subject".into(), debtor: payto.clone(), value_date: date, status: TxStatus::Completed @@ -1582,7 +1582,7 @@ mod test { &TxIn { code: 13, amount: amount.clone(), - subject: "subject".to_owned(), + subject: "subject".into(), debtor: payto.clone(), value_date: date, status: TxStatus::Completed @@ -1607,13 +1607,13 @@ mod test { Initiated { id: 1, amount: amount.clone(), - subject: "bounce: 12".to_owned(), + subject: "bounce: 12".into(), creditor: payto.clone() }, Initiated { id: 2, amount, - subject: "bounce: 13".to_owned(), + subject: "bounce: 13".into(), creditor: payto } ] diff --git a/taler-magnet-bank/src/magnet_api/types.rs b/taler-magnet-bank/src/magnet_api/types.rs @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2025 Taler Systems SA + Copyright (C) 2025, 2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -14,6 +14,7 @@ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ +use compact_str::CompactString; use jiff::Timestamp; use serde::{Deserialize, Serialize}; use taler_common::types::amount; @@ -23,9 +24,9 @@ use crate::HuIban; #[derive(Debug, Deserialize)] pub struct Consumer { #[serde(rename = "consumerKey")] - pub key: String, + pub key: CompactString, #[serde(rename = "megnevezes")] - pub name: String, + pub name: CompactString, #[serde(rename = "callbackUri")] pub callback_uri: String, #[serde(rename = "elettartam")] @@ -39,7 +40,7 @@ pub struct TokenInfo { #[serde(rename = "lejarat")] pub expiration: jiff::Timestamp, #[serde(rename = "kliensinfo")] - pub client_info: Option<String>, + pub client_info: Option<CompactString>, pub consumer: Consumer, #[serde(rename = "hitelesitett")] pub authenticated: bool, @@ -48,29 +49,29 @@ pub struct TokenInfo { #[derive(Debug, Deserialize)] pub struct SmsCodeSubmission { #[serde(rename = "csatorna")] - pub channel: String, + pub channel: CompactString, #[serde(rename = "hovaMentKi")] - pub sent_to: Vec<String>, + pub sent_to: Vec<CompactString>, } #[derive(Debug, Deserialize)] pub struct ScaResult { #[serde(rename = "csatorna")] - pub channel: String, + pub channel: CompactString, #[serde(rename = "hovaMentKi")] - pub sent_to: Vec<String>, + pub sent_to: Vec<CompactString>, } #[derive(Debug, Deserialize)] pub struct Partner { #[serde(rename = "megnevezes")] - pub name: String, + pub name: CompactString, #[serde(rename = "kod")] pub code: u64, #[serde(rename = "adoszam")] - pub tax_number: Option<String>, + pub tax_number: Option<CompactString>, #[serde(rename = "ebUfallapot")] - pub status: String, // TODO enum + pub status: CompactString, // TODO enum } #[derive(Debug, Deserialize)] @@ -78,7 +79,7 @@ pub struct AccountType { #[serde(rename = "kod")] pub code: u64, #[serde(rename = "megnevezes")] - pub name: String, + pub name: CompactString, } #[derive(Debug, Deserialize)] @@ -86,7 +87,7 @@ pub struct Currency { #[serde(rename = "jel")] pub symbol: amount::Currency, #[serde(rename = "megnevezes")] - pub name: String, + pub name: CompactString, } #[derive(Debug, Deserialize)] @@ -102,13 +103,13 @@ pub struct Account { #[serde(rename = "kod")] pub code: u64, #[serde(rename = "szamlaszam")] - pub number: String, + pub number: CompactString, #[serde(rename = "tulajdonosKod")] pub owner_code: u64, #[serde(rename = "lakossagi")] pub resident: bool, #[serde(rename = "megnevezes")] - pub name: Option<String>, + pub name: Option<CompactString>, pub partner: Partner, } @@ -204,21 +205,21 @@ pub struct Tx { #[serde(rename = "osszegSigned")] pub amount: f64, #[serde(rename = "kozlemeny")] - pub subject: Option<String>, + pub subject: Option<Box<str>>, #[serde(rename = "statusz")] pub status: TxStatus, #[serde(rename = "tranzakcioAltipus")] - pub kind: Option<String>, + pub kind: Option<CompactString>, #[serde(rename = "eredetiErteknap")] pub tx_date: jiff::civil::Date, #[serde(rename = "erteknap")] pub value_date: jiff::civil::Date, #[serde(rename = "eszamla")] - pub counter_account: String, + pub counter_account: CompactString, #[serde(rename = "epartner")] - pub counter_name: String, + pub counter_name: CompactString, #[serde(rename = "tranzakcioTipus")] - pub ty: Option<String>, + pub ty: Option<CompactString>, pub eam: Option<u64>, pub partner: Partner, } @@ -228,27 +229,27 @@ pub struct TxDto { #[serde(rename = "kod")] pub code: u64, #[serde(rename = "bankszamla")] - pub bank_account: String, + pub bank_account: CompactString, #[serde(rename = "bankszamlaTulajdonos")] - pub bank_account_owner: String, + pub bank_account_owner: CompactString, #[serde(rename = "deviza")] pub currency: amount::Currency, #[serde(rename = "osszeg")] pub amount: f64, #[serde(rename = "kozlemeny")] - pub subject: Option<String>, + pub subject: Option<Box<str>>, #[serde(rename = "statusz")] pub status: TxStatus, #[serde(rename = "tranzakcioAltipus")] - pub kind: Option<String>, + pub kind: Option<CompactString>, #[serde(rename = "eredetiErteknap")] pub tx_date: jiff::civil::Date, #[serde(rename = "erteknap")] pub value_date: jiff::civil::Date, #[serde(rename = "eszamla")] - pub counter_account: String, + pub counter_account: CompactString, #[serde(rename = "epartner")] - pub counter_name: String, + pub counter_name: CompactString, #[serde(rename = "tranzakcioTipus")] pub ty: Option<String>, pub eam: Option<u64>, diff --git a/taler-magnet-bank/tests/api.rs b/taler-magnet-bank/tests/api.rs @@ -117,7 +117,7 @@ async fn outgoing_history() { &db::TxOut { code: i as u64, amount: amount("EUR:10"), - subject: "subject".to_owned(), + subject: "subject".into(), creditor: PAYTO.clone(), value_date: now, status: TxStatus::Completed, @@ -180,7 +180,7 @@ pub async fn test_in(pool: &PgPool, key: EddsaPublicKey) { let tx = TxIn { code: rand::random_range(10..10000), amount: amount("EUR:12"), - subject: String::new(), + subject: Box::default(), debtor: PAYTO.clone(), value_date: Zoned::now().date(), status: TxStatus::Completed,