cli_option.rs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. use std::net::SocketAddr;
  2. use clap::{App, Arg, SubCommand};
  3. use super::Channel;
  4. use crate::{net::Settings, Result};
  5. pub struct CliOption {
  6. pub network_settings: Settings,
  7. pub username: Option<String>,
  8. pub channel_name: Option<String>,
  9. pub new_channel: Option<Channel>,
  10. pub verbose: bool,
  11. pub log_path: Box<std::path::PathBuf>,
  12. }
  13. impl CliOption {
  14. pub fn get() -> Result<CliOption> {
  15. let mat = App::new("DarkPulse")
  16. .version("0.0.1")
  17. .author("Dark Renaissance Technologies")
  18. .about("An anonymous p2p chat application")
  19. .arg(
  20. Arg::with_name("accept")
  21. .short("a")
  22. .value_name("ADDRESSES")
  23. .help("accept address")
  24. .long("accept")
  25. .required(true),
  26. )
  27. .arg(Arg::with_name("slots").value_name("SLOTS").long("slots").help("Connection slots"))
  28. .arg(
  29. Arg::with_name("verbose")
  30. .takes_value(false)
  31. .long("verbose")
  32. .help("increase verbosity"),
  33. )
  34. .arg(
  35. Arg::with_name("connects")
  36. .value_name("MANUAL_CONNECTS")
  37. .multiple(true)
  38. .takes_value(true)
  39. .short("c")
  40. .long("connects")
  41. .help("Manual connections"),
  42. )
  43. .arg(
  44. Arg::with_name("seed")
  45. .value_name("ADDRESSES")
  46. .multiple(true)
  47. .takes_value(true)
  48. .short("s")
  49. .long("seed")
  50. .help("Connect to the seed node"),
  51. )
  52. .arg(
  53. Arg::with_name("log")
  54. .value_name("LOG_PATH")
  55. .takes_value(true)
  56. .long("log")
  57. .help("Log file path"),
  58. )
  59. .arg(
  60. Arg::with_name("username")
  61. .value_name("USERNAME")
  62. .short("u")
  63. .long("username")
  64. .help("node's username"),
  65. )
  66. .arg(
  67. Arg::with_name("channel")
  68. .value_name("CHANNEL")
  69. .short("h")
  70. .long("channel")
  71. .help("switch to one of available channels"),
  72. )
  73. .subcommand(
  74. SubCommand::with_name("newchannel")
  75. .about("add new channel")
  76. .arg(
  77. Arg::with_name("name")
  78. .long("channelname")
  79. .required(true)
  80. .value_name("CHANNELNAME")
  81. .help("name for the new channel"),
  82. )
  83. .arg(
  84. Arg::with_name("address")
  85. .long("channeladdress")
  86. .required(true)
  87. .value_name("CHANNELADDRESS")
  88. .help("address for the new channel"),
  89. ),
  90. )
  91. .get_matches();
  92. let mut accept_addr: Option<SocketAddr> = None;
  93. if let Some(addr) = mat.value_of("accept") {
  94. accept_addr = Some(addr.parse()?);
  95. }
  96. let mut connection_slots = 0;
  97. if let Some(slots) = mat.value_of("slots") {
  98. connection_slots = slots.parse()?;
  99. };
  100. let mut seed_addresses: Vec<SocketAddr> = vec![];
  101. if let Some(seed_addrs) = mat.values_of("seed") {
  102. seed_addresses = Self::collect_addrs(seed_addrs.collect::<Vec<&str>>());
  103. };
  104. let mut manual_connects: Vec<SocketAddr> = vec![];
  105. if let Some(man_connects) = mat.values_of("connects") {
  106. manual_connects = Self::collect_addrs(man_connects.collect::<Vec<&str>>());
  107. };
  108. let mut username = None;
  109. if let Some(uname) = mat.value_of("username") {
  110. username = Some(String::from(uname));
  111. }
  112. let mut channel_name = None;
  113. if let Some(chan) = mat.value_of("channel") {
  114. channel_name = Some(String::from(chan));
  115. }
  116. let mut new_channel: Option<Channel> = None;
  117. if let Some(newch) = mat.subcommand_matches("newchannel") {
  118. let mut new_channel_name = String::new();
  119. let mut new_channel_address = String::new();
  120. if let Some(channelname) = newch.value_of("name") {
  121. new_channel_name = String::from(channelname);
  122. }
  123. if let Some(channeladdress) = newch.value_of("address") {
  124. new_channel_address = String::from(channeladdress);
  125. }
  126. new_channel = Some(Channel::gen_new_with_addr(new_channel_name, new_channel_address)?);
  127. }
  128. let verbose = mat.is_present("verbose");
  129. let log_path = Box::new(
  130. if let Some(log_path) = mat.value_of("log") {
  131. std::path::Path::new(log_path)
  132. } else {
  133. std::path::Path::new("/tmp/darkpulsenode.log")
  134. }
  135. .to_path_buf(),
  136. );
  137. let network_settings = Settings {
  138. inbound: accept_addr,
  139. outbound_connections: connection_slots,
  140. seed_query_timeout_seconds: 8,
  141. connect_timeout_seconds: 10,
  142. channel_handshake_seconds: 4,
  143. channel_heartbeat_seconds: 10,
  144. external_addr: accept_addr,
  145. peers: manual_connects,
  146. seeds: seed_addresses,
  147. };
  148. Ok(CliOption { network_settings, username, channel_name, new_channel, verbose, log_path })
  149. }
  150. fn collect_addrs(addrs: Vec<&str>) -> Vec<SocketAddr> {
  151. let addrs: Vec<SocketAddr> = addrs
  152. .iter()
  153. .map(|addr| {
  154. let addr: SocketAddr = addr.parse().expect("unable to parse on of the addresses");
  155. addr
  156. })
  157. .collect();
  158. addrs
  159. }
  160. }