gitignore_template_generator/parser/
impls.rs1use std::{ffi::OsString, process::exit};
2
3use clap::{CommandFactory, Parser};
4
5use crate::{ExitKind, ProgramExit, constant};
6
7use super::{Args, ArgsParser};
8
9pub struct DefaultArgsParser;
12
13impl DefaultArgsParser {
14 fn parse_global_options(args: &Args) -> Option<ProgramExit> {
15 if args.show_help {
16 let mut cmd = Args::command();
17 let rendered_help = cmd.render_help();
18 Some(ProgramExit {
19 message: rendered_help.to_string().trim_end().to_string(),
20 exit_status: constant::exit_status::SUCCESS,
21 styled_message: Some(
22 rendered_help.ansi().to_string().trim_end().to_string(),
23 ),
24 kind: ExitKind::HelpInfos,
25 })
26 } else if args.show_version {
27 let cmd = Args::command();
28 let message = match cmd.get_version() {
29 Some(version) => {
30 format!("{} {version}", env!("CARGO_PKG_NAME"))
31 }
32 None => constant::error_messages::VERSION_INFOS_NOT_AVAILABLE
33 .to_string(),
34 };
35
36 Some(ProgramExit {
37 message,
38 exit_status: constant::exit_status::SUCCESS,
39 styled_message: None,
40 kind: ExitKind::VersionInfos,
41 })
42 } else if args.show_author {
43 let cmd = Args::command();
44 let message = String::from(match cmd.get_author() {
45 Some(author) => author,
46 None => constant::error_messages::AUTHOR_INFOS_NOT_AVAILABLE,
47 });
48
49 Some(ProgramExit {
50 message,
51 exit_status: constant::exit_status::SUCCESS,
52 styled_message: None,
53 kind: ExitKind::AuthorInfos,
54 })
55 } else {
56 None
57 }
58 }
59
60 fn print_error_message(error: &ProgramExit, message: &str) {
61 match error.kind {
62 ExitKind::VersionInfos
63 | ExitKind::HelpInfos
64 | ExitKind::AuthorInfos => println!("{message}"),
65 ExitKind::Error => eprintln!("{message}"),
66 }
67 }
68}
69
70impl ArgsParser for DefaultArgsParser {
71 fn parse(args: impl IntoIterator<Item = OsString>) -> Args {
83 match DefaultArgsParser::try_parse(args) {
84 Ok(parsed_args) => parsed_args,
85 Err(error) => {
86 if let Some(value) = &error.styled_message {
87 Self::print_error_message(&error, value);
88 } else {
89 Self::print_error_message(&error, &error.message);
90 }
91
92 exit(error.exit_status);
93 }
94 }
95 }
96
97 fn try_parse(
98 args: impl IntoIterator<Item = OsString>,
99 ) -> Result<Args, ProgramExit> {
100 match Args::try_parse_from(args) {
101 Ok(parsed_args) => match Self::parse_global_options(&parsed_args) {
102 Some(error) => Err(error),
103 None => Ok(parsed_args),
104 },
105 Err(error) => Err(ProgramExit {
106 message: format!(
107 "{}\nFor more information, try '--help'.",
108 error.render()
109 ),
110 exit_status: error.exit_code(),
111 styled_message: Some(format!(
112 "{}\nFor more information, try '\u{1b}[1m--help\u{1b}[0m'.",
113 error.render().ansi()
114 )),
115 kind: ExitKind::Error,
116 }),
117 }
118 }
119}