main.rs (3325B)
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 clap::Parser as _; 18 use taler_api::api::TalerRouter as _; 19 use taler_build::long_version; 20 use taler_common::{CommonArgs, cli::ConfigCmd, config::Config, taler_main}; 21 use taler_wise::{ 22 CONFIG_SOURCE, api, 23 config::ServeCfg, 24 db::{dbinit, pool}, 25 setup::{self}, 26 worker::run_worker, 27 }; 28 29 #[derive(clap::Parser, Debug)] 30 #[command(long_version = long_version(), about, long_about = None)] 31 struct Args { 32 #[clap(flatten)] 33 common: CommonArgs, 34 35 #[command(subcommand)] 36 cmd: Command, 37 } 38 39 #[derive(clap::Subcommand, Debug)] 40 enum Command { 41 /// Initialize taler-wise database 42 Dbinit { 43 /// Reset database (DANGEROUS: All existing data is lost) 44 #[arg(short, long)] 45 reset: bool, 46 }, 47 /// Check taler-wise config 48 Setup, 49 /// Run taler-wise worker 50 Worker { 51 /// Execute once and return 52 #[arg(short, long)] 53 transient: bool, 54 }, 55 /// Run taler-wise HTTP server 56 Serve { 57 /// Check whether an API is in use (if it's useful to start the HTTP 58 /// server). Exit with 0 if at least one API is enabled, otherwise 1 59 #[arg(long)] 60 check: bool, 61 }, 62 #[command(subcommand)] 63 Config(ConfigCmd), 64 } 65 66 async fn run(cmd: Command, cfg: &Config) -> anyhow::Result<()> { 67 match cmd { 68 Command::Dbinit { reset } => { 69 dbinit(cfg, reset).await?; 70 } 71 Command::Setup => { 72 let client = http_client::client(); 73 setup::setup(cfg, &client).await? 74 } 75 Command::Serve { check } => { 76 if check { 77 let cfg = ServeCfg::parse(cfg)?; 78 if cfg.revenue.is_none() && cfg.wire_gateway.is_none() { 79 std::process::exit(1); 80 } 81 } else { 82 let pool = pool(cfg).await?; 83 let cfg = ServeCfg::parse(cfg)?; 84 api::start( 85 pool, 86 &cfg.name, 87 cfg.balances, 88 &cfg.wire_gateway, 89 &cfg.revenue, 90 ) 91 .await 92 .serve(&cfg.serve, None) 93 .await?; 94 } 95 } 96 Command::Worker { transient } => { 97 let pool = pool(cfg).await?; 98 let client = http_client::client(); 99 run_worker(cfg, &pool, &client, transient).await?; 100 } 101 Command::Config(cmd) => cmd.run(cfg)?, 102 } 103 Ok(()) 104 } 105 106 fn main() { 107 let args = Args::parse(); 108 taler_main(CONFIG_SOURCE, args.common, async |cfg| { 109 run(args.cmd, cfg).await 110 }); 111 }