33//! This module contains the core application logic for running the CLI.
44
55use clap:: Parser ;
6+ use thiserror:: Error ;
67
78use crate :: cli:: { Cli , Commands } ;
9+ use crate :: handlers:: check:: CheckError ;
10+ use crate :: handlers:: list:: ListError ;
811use crate :: DependencyManager ;
912
13+ /// Exit codes for the CLI application
14+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
15+ pub enum ExitCode {
16+ /// Success - all checks passed
17+ Success = 0 ,
18+ /// Missing dependencies (tool not installed or missing dependencies)
19+ MissingDependencies = 1 ,
20+ /// Invalid arguments (unknown tool name)
21+ InvalidArguments = 2 ,
22+ /// Internal error (detection failures or other errors)
23+ InternalError = 3 ,
24+ }
25+
26+ impl From < ExitCode > for i32 {
27+ fn from ( code : ExitCode ) -> Self {
28+ code as i32
29+ }
30+ }
31+
32+ /// Errors that can occur when running the application
33+ #[ derive( Debug , Error ) ]
34+ pub enum AppError {
35+ /// Failed to execute the check command
36+ ///
37+ /// This occurs when the check command fails to verify dependencies.
38+ #[ error( "Check command failed: {source}" ) ]
39+ CheckFailed {
40+ #[ source]
41+ source : CheckError ,
42+ } ,
43+
44+ /// Failed to execute the list command
45+ ///
46+ /// This occurs when the list command fails to list dependencies.
47+ #[ error( "List command failed: {source}" ) ]
48+ ListFailed {
49+ #[ source]
50+ source : ListError ,
51+ } ,
52+ }
53+
54+ impl AppError {
55+ /// Convert the error to an appropriate exit code for the CLI
56+ ///
57+ /// # Exit Codes
58+ ///
59+ /// - `ExitCode::MissingDependencies`: Tool not installed or missing dependencies
60+ /// - `ExitCode::InvalidArguments`: Unknown tool name
61+ /// - `ExitCode::InternalError`: Detection failures or other errors
62+ #[ must_use]
63+ pub fn to_exit_code ( & self ) -> ExitCode {
64+ use crate :: handlers:: check:: {
65+ CheckAllToolsError , CheckError , CheckSpecificToolError , ParseToolNameError ,
66+ } ;
67+
68+ match self {
69+ Self :: CheckFailed { source } => match source {
70+ CheckError :: CheckAllFailed { source } => match source {
71+ CheckAllToolsError :: MissingDependencies { .. } => ExitCode :: MissingDependencies ,
72+ CheckAllToolsError :: DependencyCheckFailed { .. } => ExitCode :: InternalError ,
73+ } ,
74+ CheckError :: CheckSpecificFailed { source } => match source {
75+ CheckSpecificToolError :: ParseFailed {
76+ source : ParseToolNameError :: UnknownTool { .. } ,
77+ } => ExitCode :: InvalidArguments ,
78+ CheckSpecificToolError :: ToolNotInstalled { .. } => {
79+ ExitCode :: MissingDependencies
80+ }
81+ CheckSpecificToolError :: DetectionFailed { .. } => ExitCode :: InternalError ,
82+ } ,
83+ } ,
84+ Self :: ListFailed { .. } => ExitCode :: InternalError ,
85+ }
86+ }
87+ }
88+
89+ impl From < CheckError > for AppError {
90+ fn from ( source : CheckError ) -> Self {
91+ Self :: CheckFailed { source }
92+ }
93+ }
94+
95+ impl From < ListError > for AppError {
96+ fn from ( source : ListError ) -> Self {
97+ Self :: ListFailed { source }
98+ }
99+ }
100+
10101/// Run the CLI application
11102///
12103/// # Errors
@@ -15,7 +106,7 @@ use crate::DependencyManager;
15106/// - Dependencies are missing
16107/// - Invalid tool name is provided
17108/// - Internal error occurs during dependency checking
18- pub fn run ( ) -> Result < ( ) , Box < dyn std :: error :: Error > > {
109+ pub fn run ( ) -> Result < ( ) , AppError > {
19110 let cli = Cli :: parse ( ) ;
20111
21112 // Initialize tracing based on verbose flag
@@ -29,7 +120,9 @@ pub fn run() -> Result<(), Box<dyn std::error::Error>> {
29120 let manager = DependencyManager :: new ( ) ;
30121
31122 match cli. command {
32- Commands :: Check { tool } => crate :: handlers:: check:: handle_check ( & manager, tool) ,
33- Commands :: List => crate :: handlers:: list:: handle_list ( & manager) ,
123+ Commands :: Check { tool } => crate :: handlers:: check:: handle_check ( & manager, tool) ? ,
124+ Commands :: List => crate :: handlers:: list:: handle_list ( & manager) ? ,
34125 }
126+
127+ Ok ( ( ) )
35128}
0 commit comments