urushi_prompt/runtime/
error.rs1use std::{fmt, io};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7#[non_exhaustive]
8pub enum IoOperation {
9 EnterTerminal,
11 ReadEvent,
13 Render,
15 Cleanup,
17}
18
19impl fmt::Display for IoOperation {
20 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
21 formatter.write_str(match self {
22 Self::EnterTerminal => "enter terminal session",
23 Self::ReadEvent => "read terminal event",
24 Self::Render => "render prompt",
25 Self::Cleanup => "clean up terminal session",
26 })
27 }
28}
29
30#[derive(Debug)]
32#[non_exhaustive]
33pub enum RunError {
34 NotInteractive,
36 Resized {
39 cleanup: Option<io::Error>,
41 },
42 Io {
44 operation: IoOperation,
46 source: io::Error,
48 cleanup: Option<io::Error>,
50 },
51}
52
53impl fmt::Display for RunError {
54 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
55 match self {
56 Self::NotInteractive => formatter
57 .write_str("standard input and standard error must be interactive terminals"),
58 Self::Resized {
59 cleanup: Some(cleanup),
60 } => write!(
61 formatter,
62 "terminal resized during inline prompt; terminal cleanup also failed: {cleanup}"
63 ),
64 Self::Resized { cleanup: None } => {
65 formatter.write_str("terminal resized during inline prompt")
66 }
67 Self::Io {
68 operation,
69 source,
70 cleanup: Some(cleanup),
71 } => write!(
72 formatter,
73 "failed to {operation}: {source}; terminal cleanup also failed: {cleanup}"
74 ),
75 Self::Io {
76 operation,
77 source,
78 cleanup: None,
79 } => write!(formatter, "failed to {operation}: {source}"),
80 }
81 }
82}
83
84impl std::error::Error for RunError {
85 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
86 match self {
87 Self::NotInteractive => None,
88 Self::Resized { cleanup } => cleanup
89 .as_ref()
90 .map(|error| error as &(dyn std::error::Error + 'static)),
91 Self::Io { source, .. } => Some(source),
92 }
93 }
94}
95
96#[derive(Debug, Clone, PartialEq, Eq)]
98#[non_exhaustive]
99pub enum FormBuildError {
100 EmptyForm,
102 DuplicateFieldName(String),
104}
105
106impl fmt::Display for FormBuildError {
107 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
108 match self {
109 Self::EmptyForm => formatter.write_str("a form must contain at least one group"),
110 Self::DuplicateFieldName(name) => {
111 write!(formatter, "field name `{name}` is duplicated in the form")
112 }
113 }
114 }
115}
116
117impl std::error::Error for FormBuildError {}
118
119#[derive(Debug, Clone, PartialEq, Eq)]
121#[non_exhaustive]
122pub enum GroupBuildError {
123 EmptyGroup,
125}
126
127impl fmt::Display for GroupBuildError {
128 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
129 formatter.write_str("a prompt group must contain at least one field")
130 }
131}
132
133impl std::error::Error for GroupBuildError {}
134
135#[derive(Debug, Clone, PartialEq, Eq)]
137#[non_exhaustive]
138pub enum FieldConfigError {
139 EmptyName,
141 EmptyOptions,
143}
144
145impl fmt::Display for FieldConfigError {
146 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
147 formatter.write_str(match self {
148 Self::EmptyName => "a prompt field name cannot be empty",
149 Self::EmptyOptions => "a select field must contain at least one option",
150 })
151 }
152}
153
154impl std::error::Error for FieldConfigError {}