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