valheim_mod_manager/
cli.rs1use clap::{Args, Parser, Subcommand, ValueEnum};
2use std::path::PathBuf;
3
4#[derive(Parser)]
9#[command(version, about, long_about = None)]
10pub struct AppCli {
11 #[arg(long, global = true)]
13 pub config: Option<PathBuf>,
14 #[command(subcommand)]
16 pub command: Command,
17}
18
19#[derive(Subcommand)]
21pub enum Command {
22 Update(CommandArgs),
24 Search(SearchArgs),
26 List(ListArgs),
28}
29
30#[derive(Args)]
32pub struct ListArgs {
33 #[arg(long, value_enum, default_value_t = ListFormat::Text)]
35 pub format: ListFormat,
36}
37
38#[derive(Clone, ValueEnum)]
40pub enum ListFormat {
41 Text,
43 Json,
45}
46
47#[derive(Args)]
49pub struct CommandArgs {
50 #[command(subcommand)]
52 pub command: UpdatesCommand,
53}
54
55#[derive(Args)]
57pub struct SearchArgs {
58 pub term: String,
60}
61
62#[derive(Subcommand)]
64pub enum UpdatesCommand {
65 Manifest,
67 Mods,
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74 use clap::CommandFactory;
75
76 #[test]
77 fn test_command_search() {
78 let app = AppCli::command();
79 let search_command = app.find_subcommand("search").unwrap();
80
81 assert_eq!(search_command.get_name(), "search");
82 assert!(search_command.get_about().is_some());
83 assert!(
84 search_command
85 .get_about()
86 .unwrap()
87 .to_string()
88 .contains("Search for mods by name")
89 );
90
91 let search_args = search_command.get_arguments().collect::<Vec<_>>();
92 assert_eq!(search_args.len(), 1);
93 assert_eq!(search_args[0].get_id().as_str(), "term");
94 assert!(search_args[0].get_help().is_some());
95 assert!(
96 search_args[0]
97 .get_help()
98 .unwrap()
99 .to_string()
100 .contains("Search term to find mods by name")
101 );
102 }
103
104 #[test]
105 fn test_command_update() {
106 let app = AppCli::command();
107 let update_command = app.find_subcommand("update").unwrap();
108
109 assert_eq!(update_command.get_name(), "update");
110 assert!(update_command.get_about().is_some());
111 assert!(
112 update_command
113 .get_about()
114 .unwrap()
115 .to_string()
116 .contains("Update the mod manifest or installed mods")
117 );
118
119 let update_subcommands = update_command.get_subcommands().collect::<Vec<_>>();
120 assert_eq!(update_subcommands.len(), 2);
121
122 let manifest_cmd = update_subcommands
123 .iter()
124 .find(|cmd| cmd.get_name() == "manifest")
125 .unwrap();
126 let mods_cmd = update_subcommands
127 .iter()
128 .find(|cmd| cmd.get_name() == "mods")
129 .unwrap();
130
131 assert!(manifest_cmd.get_about().is_some());
132 assert!(
133 manifest_cmd
134 .get_about()
135 .unwrap()
136 .to_string()
137 .contains("Update the mod manifest from the server")
138 );
139 assert!(mods_cmd.get_about().is_some());
140 assert!(
141 mods_cmd
142 .get_about()
143 .unwrap()
144 .to_string()
145 .contains("Update installed mods to their latest versions")
146 );
147 }
148
149 #[test]
150 fn test_command_list() {
151 let app = AppCli::command();
152 let list_command = app.find_subcommand("list").unwrap();
153
154 assert_eq!(list_command.get_name(), "list");
155 assert!(list_command.get_about().is_some());
156 assert!(
157 list_command
158 .get_about()
159 .unwrap()
160 .to_string()
161 .contains("List all mods from config including resolved dependencies")
162 );
163
164 let list_args = list_command.get_arguments().collect::<Vec<_>>();
165 let format_arg = list_args
166 .iter()
167 .find(|a| a.get_id().as_str() == "format")
168 .unwrap();
169 assert!(format_arg.get_default_values().iter().any(|v| v == "text"));
170 }
171}