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
use clap::*;

use crate::model::{ComponentName, ExampleName, GuestLanguage, GuestLanguageTier, PackageName};

#[derive(Args, Debug)]
#[group(required = true, multiple = false)]
pub struct NameOrLanguage {
    /// Name of the example to use
    #[arg(short, long, group = "ex")]
    pub example: Option<ExampleName>,

    /// Language to use for it's default example
    #[arg(short, long, alias = "lang", group = "ex")]
    pub language: Option<GuestLanguage>,
}

impl NameOrLanguage {
    /// Gets the selected example's name
    pub fn example_name(&self) -> ExampleName {
        self.example
            .clone()
            .unwrap_or(ExampleName::from_string(format!(
                "{}-default",
                self.language.clone().unwrap_or(GuestLanguage::Rust).id()
            )))
    }
}

#[derive(Subcommand, Debug)]
#[command()]
pub enum Command {
    /// Create a new Golem component from built-in examples
    #[command()]
    New {
        #[command(flatten)]
        name_or_language: NameOrLanguage,

        /// The package name of the generated component (in namespace:name format)
        #[arg(short, long)]
        package_name: Option<PackageName>,

        /// The new component's name
        component_name: ComponentName,
    },

    /// Lists the built-in examples available for creating new components
    #[command()]
    ListExamples {
        /// The minimum language tier to include in the list
        #[arg(short, long)]
        min_tier: Option<GuestLanguageTier>,

        /// Filter examples by a given guest language
        #[arg(short, long, alias = "lang")]
        language: Option<GuestLanguage>,
    },
}

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None, rename_all = "kebab-case")]
pub struct GolemCommand {
    #[command(subcommand)]
    pub command: Command,
}