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