open_editor/
errors.rs

1use std::{fmt::Display, path::PathBuf};
2
3#[derive(Debug)]
4/// Errors that can occur when trying to open an editor.
5pub enum OpenEditorError {
6    NoEditorFound,
7    EditorCallError {
8        exit_code: Option<i32>,
9        stderr: String,
10    },
11    CommandFail {
12        error: std::io::Error,
13    },
14    EditorNotFound {
15        binary_path: PathBuf,
16    },
17    EditorNotExecutable {
18        binary_path: PathBuf,
19        error: Option<std::io::Error>,
20    },
21    FileManipulationFail(std::io::Error),
22    TempFileCleanupFail(String),
23}
24impl Display for OpenEditorError {
25    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26        match self {
27            OpenEditorError::NoEditorFound => write!(f, "No editor found in the system path."),
28            OpenEditorError::EditorCallError { exit_code, stderr } => write!(
29                f,
30                "Editor call failed with exit code {exit_code:?} and stderr: {stderr}"
31            ),
32            OpenEditorError::CommandFail { error } => {
33                write!(f, "Command failed: {error:?}")
34            }
35            OpenEditorError::EditorNotFound { binary_path } => write!(
36                f,
37                "Editor binary not found at path: {}",
38                binary_path.display()
39            ),
40            OpenEditorError::EditorNotExecutable {
41                error: _,
42                binary_path,
43            } => write!(
44                f,
45                "Editor binary is not executable at path: {}",
46                binary_path.display()
47            ),
48            OpenEditorError::FileManipulationFail(error) => {
49                write!(f, "Failed to read file: {error}")
50            }
51            OpenEditorError::TempFileCleanupFail(filename) => {
52                write!(f, "Failed to clean up temporary file: {filename}")
53            }
54        }
55    }
56}
57impl std::error::Error for OpenEditorError {
58    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
59        match self {
60            OpenEditorError::EditorCallError {
61                exit_code: _,
62                stderr: _,
63            } => todo!(),
64            OpenEditorError::CommandFail { error }
65            | OpenEditorError::FileManipulationFail(error) => Some(error),
66            OpenEditorError::EditorNotFound { binary_path: _ } | OpenEditorError::NoEditorFound => {
67                None
68            }
69            OpenEditorError::EditorNotExecutable {
70                binary_path: _,
71                error,
72            } => error.as_ref().map(|e| e as &dyn std::error::Error),
73            OpenEditorError::TempFileCleanupFail(_) => None,
74        }
75    }
76}