1use std::str::FromStr;
2
3use clap::{command, CommandFactory, FromArgMatches, Parser};
4
5pub mod build;
6pub mod dev;
7pub mod init;
8pub mod update_env;
9
10const ABOUT: &str = "Build contracts and generate front ends";
11
12const LONG_ABOUT: &str = "loam-sdk also helps when writing smart contracts.";
14
15#[derive(Parser, Debug)]
16#[command(
17 name = "loam",
18 about = ABOUT,
19 long_about = ABOUT.to_string() + LONG_ABOUT,
20 disable_help_subcommand = true,
21)]
22pub struct Root {
23 #[command(subcommand)]
24 pub cmd: Cmd,
25}
26
27impl Root {
28 pub fn new() -> Result<Self, clap::Error> {
29 let mut matches = Self::command().get_matches();
30 Self::from_arg_matches_mut(&mut matches)
31 }
32
33 pub fn from_arg_matches<I, T>(itr: I) -> Result<Self, clap::Error>
34 where
35 I: IntoIterator<Item = T>,
36 T: Into<std::ffi::OsString> + Clone,
37 {
38 Self::from_arg_matches_mut(&mut Self::command().get_matches_from(itr))
39 }
40 pub async fn run(&mut self) -> Result<(), Error> {
41 match &mut self.cmd {
42 Cmd::Init(init_info) => init_info.run()?,
43 Cmd::Build(build_info) => build_info.run().await?,
44 Cmd::UpdateEnv(e) => e.run()?,
45 Cmd::Dev(dev_info) => dev_info.run().await?,
46 };
47 Ok(())
48 }
49}
50
51impl FromStr for Root {
52 type Err = clap::Error;
53
54 fn from_str(s: &str) -> Result<Self, Self::Err> {
55 Self::from_arg_matches(s.split_whitespace())
56 }
57}
58
59#[derive(Parser, Debug)]
60pub enum Cmd {
61 Init(init::Cmd),
63
64 Build(build::Cmd),
66
67 UpdateEnv(update_env::Cmd),
69
70 Dev(dev::Cmd),
72}
73
74#[derive(thiserror::Error, Debug)]
75pub enum Error {
76 #[error(transparent)]
78 Init(#[from] init::Error),
79 #[error(transparent)]
80 BuildContracts(#[from] build::Error),
81 #[error(transparent)]
82 UpdateEnv(#[from] update_env::Error),
83 #[error(transparent)]
84 Dev(#[from] dev::Error),
85}