| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- mod cli;
- mod config;
- mod helper;
- mod multi_map;
- mod protocol;
- mod transport;
- pub use cli::Cli;
- pub use config::Config;
- use anyhow::{anyhow, Result};
- use tokio::sync::broadcast;
- use tracing::debug;
- #[cfg(feature = "client")]
- mod client;
- #[cfg(feature = "client")]
- use client::run_client;
- #[cfg(feature = "server")]
- mod server;
- #[cfg(feature = "server")]
- use server::run_server;
- pub async fn run(args: &Cli, shutdown_rx: broadcast::Receiver<bool>) -> Result<()> {
- let config = Config::from_file(&args.config_path).await?;
- debug!("{:?}", config);
- // Raise `nofile` limit on linux and mac
- fdlimit::raise_fd_limit();
- match determine_run_mode(&config, args) {
- RunMode::Undetermine => Err(anyhow!("Cannot determine running as a server or a client")),
- RunMode::Client => {
- #[cfg(not(feature = "client"))]
- crate::helper::feature_not_compile("client");
- #[cfg(feature = "client")]
- run_client(&config, shutdown_rx).await
- }
- RunMode::Server => {
- #[cfg(not(feature = "server"))]
- crate::helper::feature_not_compile("server");
- #[cfg(feature = "server")]
- run_server(&config, shutdown_rx).await
- }
- }
- }
- #[derive(PartialEq, Eq, Debug)]
- enum RunMode {
- Server,
- Client,
- Undetermine,
- }
- fn determine_run_mode(config: &Config, args: &Cli) -> RunMode {
- use RunMode::*;
- if args.client && args.server {
- Undetermine
- } else if args.client {
- Client
- } else if args.server {
- Server
- } else if config.client.is_some() && config.server.is_none() {
- Client
- } else if config.server.is_some() && config.client.is_none() {
- Server
- } else {
- Undetermine
- }
- }
- #[cfg(test)]
- mod tests {
- use super::*;
- #[test]
- fn test_determine_run_mode() {
- use config::*;
- use RunMode::*;
- struct T {
- cfg_s: bool,
- cfg_c: bool,
- arg_s: bool,
- arg_c: bool,
- run_mode: RunMode,
- }
- let tests = [
- T {
- cfg_s: false,
- cfg_c: false,
- arg_s: false,
- arg_c: false,
- run_mode: Undetermine,
- },
- T {
- cfg_s: true,
- cfg_c: false,
- arg_s: false,
- arg_c: false,
- run_mode: Server,
- },
- T {
- cfg_s: false,
- cfg_c: true,
- arg_s: false,
- arg_c: false,
- run_mode: Client,
- },
- T {
- cfg_s: true,
- cfg_c: true,
- arg_s: false,
- arg_c: false,
- run_mode: Undetermine,
- },
- T {
- cfg_s: true,
- cfg_c: true,
- arg_s: true,
- arg_c: false,
- run_mode: Server,
- },
- T {
- cfg_s: true,
- cfg_c: true,
- arg_s: false,
- arg_c: true,
- run_mode: Client,
- },
- T {
- cfg_s: true,
- cfg_c: true,
- arg_s: true,
- arg_c: true,
- run_mode: Undetermine,
- },
- ];
- for t in tests {
- let config = Config {
- server: match t.cfg_s {
- true => Some(ServerConfig::default()),
- false => None,
- },
- client: match t.cfg_c {
- true => Some(ClientConfig::default()),
- false => None,
- },
- };
- let args = Cli {
- config_path: std::path::PathBuf::new(),
- server: t.arg_s,
- client: t.arg_c,
- };
- assert_eq!(determine_run_mode(&config, &args), t.run_mode);
- }
- }
- }
|