1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
use std::convert::TryFrom; use chrono::{DateTime, Duration, FixedOffset}; use crate::error::{Error, Result}; pub enum Args { L1(L1Args), L2(L2Args), Backup(BackupArgs), Rpc(RpcArgs), } pub enum L1Args { Stop, Start, Restart, Status, ResetData { peer_store: bool }, } pub struct L2Args {} pub struct BackupArgs { pub(crate) logs_around: (DateTime<FixedOffset>, DateTime<FixedOffset>), pub(crate) peer_store: bool, } pub enum RpcArgs { GetPeers { stats: bool }, } impl Args { pub fn load_from_inputs() -> Result<Self> { let yaml = clap::load_yaml!("argument.yaml"); let matches = clap::App::from_yaml(yaml) .version(clap::crate_version!()) .author(clap::crate_authors!("\n")) .get_matches(); Self::try_from(&matches) } } impl<'a> TryFrom<&'a clap::ArgMatches<'a>> for Args { type Error = Error; fn try_from(matches: &'a clap::ArgMatches) -> Result<Self> { match matches.subcommand() { ("l1", Some(matches)) => L1Args::try_from(matches).map(Self::L1), ("l2", Some(matches)) => L2Args::try_from(matches).map(Self::L2), ("backup", Some(matches)) => BackupArgs::try_from(matches).map(Self::Backup), ("rpc", Some(matches)) => RpcArgs::try_from(matches).map(Self::Rpc), _ => unreachable!(), } } } impl<'a> TryFrom<&'a clap::ArgMatches<'a>> for L1Args { type Error = Error; fn try_from(matches: &'a clap::ArgMatches) -> Result<Self> { match matches.subcommand() { ("start", Some(_matches)) => Ok(Self::Start), ("stop", Some(_matches)) => Ok(Self::Stop), ("restart", Some(_matches)) => Ok(Self::Restart), ("status", Some(_matches)) => Ok(Self::Status), ("reset-data", Some(matches)) => { let peer_store = matches.is_present("peer-store"); Ok(Self::ResetData { peer_store }) } _ => unreachable!(), } } } impl<'a> TryFrom<&'a clap::ArgMatches<'a>> for L2Args { type Error = Error; fn try_from(_matches: &'a clap::ArgMatches) -> Result<Self> { Ok(Self {}) } } impl<'a> TryFrom<&'a clap::ArgMatches<'a>> for BackupArgs { type Error = Error; fn try_from(matches: &'a clap::ArgMatches) -> Result<Self> { let logs_around = matches .value_of("logs-around") .map(|s| { DateTime::parse_from_rfc3339(s) .map_err(|err| { Error::Arg(format!("failed to parse \"logs-around\" since {}", err)) }) .map(|base| { let dur = Duration::minutes(10); (base - dur, base + dur) }) }) .unwrap_or_else(|| unreachable!())?; let peer_store = matches.is_present("peer-store"); Ok(Self { logs_around, peer_store, }) } } impl<'a> TryFrom<&'a clap::ArgMatches<'a>> for RpcArgs { type Error = Error; fn try_from(matches: &'a clap::ArgMatches) -> Result<Self> { match matches.subcommand() { ("get_peers", Some(matches)) => { let stats = matches.is_present("stats"); Ok(Self::GetPeers { stats }) } _ => unreachable!(), } } }