1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//! # Error Types
//!
//! ##
//!
//! This module contains error types that group together some of the more specific errors returned
//! by components and utilities in this crate.
use crate::actions::Action;
use crate::commands::CommandError;
use crate::editing::application::ApplicationInfo;
use crate::key::MacroError;
use crate::keybindings::dialog::Dialog;
use crate::prelude::*;

/// Errors returned from editing operation.
#[derive(thiserror::Error, Debug)]
#[non_exhaustive]
pub enum EditError<I: ApplicationInfo> {
    /// Run an interactive dialog to determine how to complete this action.
    #[error("That action requires interactive confirmation")]
    NeedConfirm(Box<dyn Dialog<Action<I>>>),

    /// Failure to fetch a word at a cursor position.
    #[error("No word underneath cursor")]
    NoCursorWord,

    /// Failure to determine a search expression to use.
    #[error("No current search specified")]
    NoSearch,

    /// Failure due to lack of a current selection.
    #[error("No current selection")]
    NoSelection,

    /// Failure due to an umapped digraph.
    #[error("Invalid digraph: {0:?} {1:?}")]
    InvalidDigraph(char, char),

    /// Failure due to a bad regular expression.
    #[error("Invalid regular expression: {0}")]
    InvalidRegex(#[from] regex::Error),

    /// Failure due to an unset [Mark].
    #[error("Mark not set")]
    MarkNotSet(Mark),

    /// Failure due to referencing a cursor position in another buffer.
    #[error("Position is located in another buffer")]
    WrongBuffer(I::ContentId),

    /// Failure while combining cursor groups.
    #[error("Failed to combine cursor groups: {0}")]
    CursorGroupCombine(#[from] crate::editing::cursor::CursorGroupCombineError),

    /// Failure due to invalid input where an integer was expected.
    #[error("Integer conversion error: {0}")]
    IntConversionError(#[from] std::num::TryFromIntError),

    /// Failure due to invalid input where an integer was expected.
    #[error("Integer parsing error: {0}")]
    IntParseError(#[from] std::num::ParseIntError),

    /// Failure due to an unimplemented feature.
    #[error("Buffer is read-only")]
    ReadOnly,

    /// Failure due to an unimplemented feature.
    #[error("Unimplemented: {0}")]
    Unimplemented(String),

    /// Macro-related failure.
    #[error("Macro error: {0}")]
    MacroFailure(#[from] MacroError),

    /// Error while getting or putting a value into the register store.
    #[error("Register Error: {0}")]
    Register(#[from] crate::editing::store::RegisterError),

    /// Generic failure.
    #[error("Error: {0}")]
    Failure(String),
}

/// Wrapper for various Errors that consumers may want to combine.
#[derive(thiserror::Error, Debug)]
#[non_exhaustive]
pub enum UIError<I>
where
    I: ApplicationInfo,
{
    /// Failure in application-specific code.
    #[error("{0}")]
    Application(I::Error),

    /// Failure during Input/Output.
    #[error("Input/Output Error: {0}")]
    IOError(#[from] std::io::Error),

    /// Failure during editing.
    #[error("Editing error: {0}")]
    EditingFailure(#[from] EditError<I>),

    /// Failure while attempting to execute a command.
    #[error("Failed command: {0}")]
    CommandFailure(#[from] CommandError),

    /// Run an interactive dialog to determine how to complete this action.
    #[error("That action requires interactive confirmation")]
    NeedConfirm(Box<dyn Dialog<Action<I>>>),

    /// Failure while attempting to jump to previous positions.
    #[error("No previous positions in list")]
    NoList(PositionList),

    /// Failure when there's no currently selected tab.
    #[error("No tab currently selected")]
    NoTab,

    /// Failure when there's no currently selected window.
    #[error("No window currently selected")]
    NoWindow,

    /// Failure due to an unimplemented feature.
    #[error("Unimplemented: {0}")]
    Unimplemented(String),

    /// Generic failure.
    #[error("Error: {0}")]
    Failure(String),
}

/// Common result type for editing operations.
pub type EditResult<V, I> = Result<V, EditError<I>>;

/// Common result type for rendering and application functions.
pub type UIResult<V, I> = Result<V, UIError<I>>;