lib.rs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. mod cli;
  2. mod config;
  3. mod helper;
  4. mod multi_map;
  5. mod protocol;
  6. mod transport;
  7. pub use cli::Cli;
  8. pub use config::Config;
  9. use anyhow::{anyhow, Result};
  10. use tokio::sync::broadcast;
  11. use tracing::debug;
  12. #[cfg(feature = "client")]
  13. mod client;
  14. #[cfg(feature = "client")]
  15. use client::run_client;
  16. #[cfg(feature = "server")]
  17. mod server;
  18. #[cfg(feature = "server")]
  19. use server::run_server;
  20. pub async fn run(args: &Cli, shutdown_rx: broadcast::Receiver<bool>) -> Result<()> {
  21. let config = Config::from_file(&args.config_path).await?;
  22. debug!("{:?}", config);
  23. // Raise `nofile` limit on linux and mac
  24. fdlimit::raise_fd_limit();
  25. match determine_run_mode(&config, args) {
  26. RunMode::Undetermine => Err(anyhow!("Cannot determine running as a server or a client")),
  27. RunMode::Client => {
  28. #[cfg(not(feature = "client"))]
  29. crate::helper::feature_not_compile("client");
  30. #[cfg(feature = "client")]
  31. run_client(&config, shutdown_rx).await
  32. }
  33. RunMode::Server => {
  34. #[cfg(not(feature = "server"))]
  35. crate::helper::feature_not_compile("server");
  36. #[cfg(feature = "server")]
  37. run_server(&config, shutdown_rx).await
  38. }
  39. }
  40. }
  41. #[derive(PartialEq, Eq, Debug)]
  42. enum RunMode {
  43. Server,
  44. Client,
  45. Undetermine,
  46. }
  47. fn determine_run_mode(config: &Config, args: &Cli) -> RunMode {
  48. use RunMode::*;
  49. if args.client && args.server {
  50. Undetermine
  51. } else if args.client {
  52. Client
  53. } else if args.server {
  54. Server
  55. } else if config.client.is_some() && config.server.is_none() {
  56. Client
  57. } else if config.server.is_some() && config.client.is_none() {
  58. Server
  59. } else {
  60. Undetermine
  61. }
  62. }
  63. #[cfg(test)]
  64. mod tests {
  65. use super::*;
  66. #[test]
  67. fn test_determine_run_mode() {
  68. use config::*;
  69. use RunMode::*;
  70. struct T {
  71. cfg_s: bool,
  72. cfg_c: bool,
  73. arg_s: bool,
  74. arg_c: bool,
  75. run_mode: RunMode,
  76. }
  77. let tests = [
  78. T {
  79. cfg_s: false,
  80. cfg_c: false,
  81. arg_s: false,
  82. arg_c: false,
  83. run_mode: Undetermine,
  84. },
  85. T {
  86. cfg_s: true,
  87. cfg_c: false,
  88. arg_s: false,
  89. arg_c: false,
  90. run_mode: Server,
  91. },
  92. T {
  93. cfg_s: false,
  94. cfg_c: true,
  95. arg_s: false,
  96. arg_c: false,
  97. run_mode: Client,
  98. },
  99. T {
  100. cfg_s: true,
  101. cfg_c: true,
  102. arg_s: false,
  103. arg_c: false,
  104. run_mode: Undetermine,
  105. },
  106. T {
  107. cfg_s: true,
  108. cfg_c: true,
  109. arg_s: true,
  110. arg_c: false,
  111. run_mode: Server,
  112. },
  113. T {
  114. cfg_s: true,
  115. cfg_c: true,
  116. arg_s: false,
  117. arg_c: true,
  118. run_mode: Client,
  119. },
  120. T {
  121. cfg_s: true,
  122. cfg_c: true,
  123. arg_s: true,
  124. arg_c: true,
  125. run_mode: Undetermine,
  126. },
  127. ];
  128. for t in tests {
  129. let config = Config {
  130. server: match t.cfg_s {
  131. true => Some(ServerConfig::default()),
  132. false => None,
  133. },
  134. client: match t.cfg_c {
  135. true => Some(ClientConfig::default()),
  136. false => None,
  137. },
  138. };
  139. let args = Cli {
  140. config_path: std::path::PathBuf::new(),
  141. server: t.arg_s,
  142. client: t.arg_c,
  143. };
  144. assert_eq!(determine_run_mode(&config, &args), t.run_mode);
  145. }
  146. }
  147. }