ferroui_base/input/platform/
clipboard_error.rs1use std::error::Error;
2use std::fmt;
3
4#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
18pub enum ClipboardErrorKind {
19 Timeout,
22 Canceled,
24 AccessDenied,
26 Platform,
29 Other,
32}
33
34impl ClipboardErrorKind {
35 fn description(self) -> &'static str {
36 match self {
37 ClipboardErrorKind::Timeout => "The clipboard operation has timed out.",
38 ClipboardErrorKind::Canceled => "The clipboard operation was canceled.",
39 ClipboardErrorKind::AccessDenied => "Access to the clipboard was denied.",
40 ClipboardErrorKind::Platform => "A platform clipboard call failed.",
41 ClipboardErrorKind::Other => "The clipboard operation failed.",
42 }
43 }
44}
45
46#[derive(Clone, Debug, PartialEq, Eq)]
49pub struct ClipboardError {
50 kind: ClipboardErrorKind,
51 message: String,
52 code: Option<i32>,
53}
54
55impl ClipboardError {
56 pub fn new(kind: ClipboardErrorKind, message: impl Into<String>) -> ClipboardError {
58 ClipboardError { kind, message: message.into(), code: None }
59 }
60
61 pub fn from_kind(kind: ClipboardErrorKind) -> ClipboardError {
63 ClipboardError::new(kind, kind.description())
64 }
65
66 pub fn timeout(message: impl Into<String>) -> ClipboardError {
68 ClipboardError::new(ClipboardErrorKind::Timeout, message)
69 }
70
71 pub fn canceled(message: impl Into<String>) -> ClipboardError {
73 ClipboardError::new(ClipboardErrorKind::Canceled, message)
74 }
75
76 pub fn access_denied(message: impl Into<String>) -> ClipboardError {
78 ClipboardError::new(ClipboardErrorKind::AccessDenied, message)
79 }
80
81 pub fn platform(code: i32, message: impl Into<String>) -> ClipboardError {
84 ClipboardError { kind: ClipboardErrorKind::Platform, message: message.into(), code: Some(code) }
85 }
86
87 pub fn other(message: impl Into<String>) -> ClipboardError {
89 ClipboardError::new(ClipboardErrorKind::Other, message)
90 }
91
92 pub fn kind(&self) -> ClipboardErrorKind {
94 self.kind
95 }
96
97 pub fn message(&self) -> &str {
99 &self.message
100 }
101
102 pub fn code(&self) -> Option<i32> {
105 self.code
106 }
107}
108
109impl From<ClipboardErrorKind> for ClipboardError {
110 fn from(kind: ClipboardErrorKind) -> ClipboardError {
111 ClipboardError::from_kind(kind)
112 }
113}
114
115impl fmt::Display for ClipboardError {
116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117 f.write_str(&self.message)?;
118 if let Some(code) = self.code {
119 write!(f, " (0x{:08X})", code as u32)?;
120 }
121 Ok(())
122 }
123}
124
125impl Error for ClipboardError {}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130
131 #[test]
132 fn constructors_set_the_kind_the_message_and_the_code() {
133 let cases = [
134 (ClipboardError::timeout("a"), ClipboardErrorKind::Timeout),
135 (ClipboardError::canceled("a"), ClipboardErrorKind::Canceled),
136 (ClipboardError::access_denied("a"), ClipboardErrorKind::AccessDenied),
137 (ClipboardError::other("a"), ClipboardErrorKind::Other),
138 ];
139 for (error, kind) in cases {
140 assert_eq!(kind, error.kind());
141 assert_eq!("a", error.message());
142 assert_eq!(None, error.code());
143 assert_eq!("a", error.to_string());
144 }
145
146 let error = ClipboardError::platform(0x8000_4005_u32 as i32, "Native call failed");
147 assert_eq!(ClipboardErrorKind::Platform, error.kind());
148 assert_eq!(Some(0x8000_4005_u32 as i32), error.code());
149 assert_eq!("Native call failed (0x80004005)", error.to_string());
150 }
151
152 #[test]
153 fn an_error_of_a_kind_has_the_message_of_the_kind() {
154 let error: ClipboardError = ClipboardErrorKind::Timeout.into();
155 assert_eq!(ClipboardErrorKind::Timeout, error.kind());
156 assert_eq!("The clipboard operation has timed out.", error.message());
157 assert_eq!(error, ClipboardError::from_kind(ClipboardErrorKind::Timeout));
158 assert_ne!(error, ClipboardError::from_kind(ClipboardErrorKind::Canceled));
159
160 let error: &dyn Error = &error;
161 assert!(error.source().is_none());
162 }
163}