config.rs (4380B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2026 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 std::time::Duration; 18 19 use compact_str::CompactString; 20 use taler_api::{ 21 Serve, 22 config::{ApiCfg, DbCfg}, 23 }; 24 use taler_common::{ 25 config::{Config, ValueErr}, 26 map_config, 27 types::{ 28 amount::Currency, 29 payto::{ACH, BankID}, 30 }, 31 }; 32 33 use crate::payto::WiseAccount; 34 35 #[derive(Debug, Clone, Copy)] 36 pub enum AccountType { 37 Exchange, 38 Normal, 39 } 40 41 pub fn parse_db_cfg(cfg: &Config) -> Result<DbCfg, ValueErr> { 42 DbCfg::parse(cfg.section("wisedb-postgres")) 43 } 44 45 pub struct WiseBalance { 46 pub id: u32, 47 pub currency: Currency, 48 pub payto: WiseAccount, 49 } 50 51 fn balances(cfg: &Config) -> Result<Vec<WiseBalance>, ValueErr> { 52 cfg.sections() 53 .filter_map(|s| { 54 (|| { 55 Ok(if s.name.starts_with("wise-balance") { 56 Some(WiseBalance { 57 id: s.number("id").require()?, 58 currency: s.currency("currency").require()?, 59 payto: map_config!(s, "payto type", "PAYTO_TYPE", 60 "iban" => { 61 WiseAccount::IBAN(BankID { 62 iban: s.parse("IBAN", "iban").require()?, 63 bic: s.parse("BIC", "bic").opt()? 64 }) 65 }, 66 "ach" => { 67 WiseAccount::ACH(ACH { 68 routing_number: s.parse("ACH routing number", "routing_number").require()?, 69 account_number: s.parse("ACH account_number", "account_number").require()? 70 }) 71 }, 72 ) 73 .require()?, 74 }) 75 } else { 76 None 77 }) 78 })() 79 .transpose() 80 }) 81 .collect() 82 } 83 84 /// taler-wise setup config 85 pub struct SetupCfg { 86 pub token: String, 87 pub profile_id: Option<u64>, 88 pub name: Option<CompactString>, 89 pub balances: Vec<WiseBalance>, 90 } 91 92 impl SetupCfg { 93 pub fn parse(cfg: &Config) -> Result<Self, ValueErr> { 94 let s = cfg.section("wise-worker"); 95 Ok(Self { 96 profile_id: s.number("PROFILE_ID").opt()?, 97 token: s.str("TOKEN").require()?, 98 name: cfg.section("wise").cstr("NAME").opt()?, 99 balances: balances(cfg)?, 100 }) 101 } 102 } 103 104 /// taler-wise httpd config 105 pub struct ServeCfg { 106 pub name: CompactString, 107 pub serve: Serve, 108 pub balances: Vec<WiseBalance>, 109 pub wire_gateway: Option<ApiCfg>, 110 pub revenue: Option<ApiCfg>, 111 } 112 113 impl ServeCfg { 114 pub fn parse(cfg: &Config) -> Result<Self, ValueErr> { 115 let s = cfg.section("wise"); 116 Ok(Self { 117 name: s.cstr("NAME").require()?, 118 serve: Serve::parse(&cfg.section("wise-httpd"))?, 119 wire_gateway: ApiCfg::parse(cfg.section("wise-httpd-wire-gateway-api"))?, 120 revenue: ApiCfg::parse(cfg.section("wise-httpd-revenue-api"))?, 121 balances: balances(cfg)?, 122 }) 123 } 124 } 125 126 /// taler-wise worker config 127 pub struct WorkerCfg { 128 pub profile_id: u64, 129 pub token: String, 130 pub frequency: Duration, 131 pub balances: Vec<WiseBalance>, 132 } 133 134 impl WorkerCfg { 135 pub fn parse(cfg: &Config) -> Result<Self, ValueErr> { 136 let s = cfg.section("wise-worker"); 137 Ok(Self { 138 profile_id: s.number("PROFILE_ID").require()?, 139 token: s.str("TOKEN").require()?, 140 frequency: s.duration("FREQUENCY").require()?, 141 balances: balances(cfg)?, 142 }) 143 } 144 }