1use clap::Parser;
2
3use crate::cmds::project::{ProjectListCliArgs, ProjectMetadataGetCliArgs};
4
5use super::common::{validate_domain_project_repo_path, GetArgs, ListArgs};
6
7#[derive(Parser)]
8pub struct ProjectCommand {
9 #[clap(subcommand)]
10 subcommand: ProjectSubcommand,
11}
12
13#[derive(Parser)]
14enum ProjectSubcommand {
15 #[clap(about = "Gather project information metadata")]
16 Info(ProjectInfo),
17 #[clap(about = "List project members")]
18 Members(ListMembers),
19 #[clap(about = "List project/repository tags")]
20 Tags(ListProject),
21}
22
23#[derive(Parser)]
24struct ProjectInfo {
25 #[clap(long, group = "id_or_repo")]
27 pub id: Option<i64>,
28 #[clap(long, group = "id_or_repo", value_name = "DOMAIN/OWNER/PROJECT_NAME",
30 value_parser=validate_domain_project_repo_path)]
31 pub repo: Option<String>,
32 #[clap(flatten)]
33 pub get_args: GetArgs,
34}
35
36#[derive(Parser)]
37pub struct ListMembers {
38 #[clap(flatten)]
39 pub list_args: ListArgs,
40}
41
42#[derive(Parser)]
43pub struct ListProject {
44 #[clap(flatten)]
45 pub list_args: ListArgs,
46}
47
48impl From<ProjectCommand> for ProjectOptions {
49 fn from(options: ProjectCommand) -> Self {
50 match options.subcommand {
51 ProjectSubcommand::Info(options) => options.into(),
52 ProjectSubcommand::Tags(options) => options.into(),
53 ProjectSubcommand::Members(options) => options.into(),
54 }
55 }
56}
57
58impl From<ProjectInfo> for ProjectOptions {
59 fn from(options: ProjectInfo) -> Self {
60 ProjectOptions::Info(
61 ProjectMetadataGetCliArgs::builder()
62 .id(options.id)
63 .path(options.repo)
64 .get_args(options.get_args.into())
65 .build()
66 .unwrap(),
67 )
68 }
69}
70
71impl From<ListProject> for ProjectOptions {
72 fn from(options: ListProject) -> Self {
73 ProjectOptions::Tags(
74 ProjectListCliArgs::builder()
75 .list_args(options.list_args.into())
76 .tags(true)
77 .build()
78 .unwrap(),
79 )
80 }
81}
82
83impl From<ListMembers> for ProjectOptions {
84 fn from(options: ListMembers) -> Self {
85 ProjectOptions::Members(
86 ProjectListCliArgs::builder()
87 .list_args(options.list_args.into())
88 .members(true)
89 .build()
90 .unwrap(),
91 )
92 }
93}
94
95pub enum ProjectOptions {
96 Info(ProjectMetadataGetCliArgs),
97 Tags(ProjectListCliArgs),
98 Members(ProjectListCliArgs),
99}
100
101#[cfg(test)]
102mod test {
103 use crate::cli::{Args, Command};
104
105 use super::*;
106
107 #[test]
108 fn test_project_cli_info() {
109 let args = Args::parse_from(vec!["gr", "pj", "info", "--id", "1"]);
110 let project_info = match args.command {
111 Command::Project(ProjectCommand {
112 subcommand: ProjectSubcommand::Info(options),
113 }) => {
114 assert_eq!(options.id, Some(1));
115 options
116 }
117 _ => panic!("Expected ProjectCommand::Info"),
118 };
119 let options: ProjectOptions = project_info.into();
120 match options {
121 ProjectOptions::Info(options) => {
122 assert_eq!(options.id, Some(1));
123 }
124 _ => panic!("Expected ProjectOptions::Info"),
125 }
126 }
127
128 #[test]
129 fn test_project_cli_list_tags() {
130 let args = Args::parse_from(vec!["gr", "pj", "tags"]);
131 let list_project = match args.command {
132 Command::Project(ProjectCommand {
133 subcommand: ProjectSubcommand::Tags(options),
134 }) => options,
135 _ => panic!("Expected ProjectCommand::Tags"),
136 };
137 let options: ProjectOptions = list_project.into();
138 match options {
139 ProjectOptions::Tags(cli_args) => {
140 assert!(cli_args.tags);
141 assert!(!cli_args.stars);
142 assert!(!cli_args.members);
143 }
144 _ => panic!("Expected ProjectOptions::Tags"),
145 }
146 }
147
148 #[test]
149 fn test_project_cli_list_members() {
150 let args = Args::parse_from(vec!["gr", "pj", "members"]);
151 let list_members = match args.command {
152 Command::Project(ProjectCommand {
153 subcommand: ProjectSubcommand::Members(options),
154 }) => options,
155 _ => panic!("Expected ProjectCommand::Members"),
156 };
157 let options: ProjectOptions = list_members.into();
158 match options {
159 ProjectOptions::Members(cli_args) => {
160 assert!(cli_args.members);
161 assert!(!cli_args.stars);
162 assert!(!cli_args.tags);
163 }
164 _ => panic!("Expected ProjectOptions::Members"),
165 }
166 }
167}