aws_smithy_types/error/
metadata.rs
1use crate::retry::{ErrorKind, ProvideErrorKind};
9use std::collections::HashMap;
10use std::fmt;
11
12pub trait ProvideErrorMetadata {
14 fn meta(&self) -> &ErrorMetadata;
17
18 fn code(&self) -> Option<&str> {
20 self.meta().code()
21 }
22
23 fn message(&self) -> Option<&str> {
25 self.meta().message()
26 }
27}
28
29pub const EMPTY_ERROR_METADATA: ErrorMetadata = ErrorMetadata {
31 code: None,
32 message: None,
33 extras: None,
34};
35
36#[derive(Debug, Eq, PartialEq, Default, Clone)]
42pub struct ErrorMetadata {
43 code: Option<String>,
44 message: Option<String>,
45 extras: Option<HashMap<&'static str, String>>,
46}
47
48impl ProvideErrorMetadata for ErrorMetadata {
49 fn meta(&self) -> &ErrorMetadata {
50 self
51 }
52}
53
54#[derive(Debug, Default)]
56pub struct Builder {
57 inner: ErrorMetadata,
58}
59
60impl Builder {
61 pub fn message(mut self, message: impl Into<String>) -> Self {
63 self.inner.message = Some(message.into());
64 self
65 }
66
67 pub fn code(mut self, code: impl Into<String>) -> Self {
69 self.inner.code = Some(code.into());
70 self
71 }
72
73 pub fn custom(mut self, key: &'static str, value: impl Into<String>) -> Self {
99 if self.inner.extras.is_none() {
100 self.inner.extras = Some(HashMap::new());
101 }
102 self.inner
103 .extras
104 .as_mut()
105 .unwrap()
106 .insert(key, value.into());
107 self
108 }
109
110 pub fn build(self) -> ErrorMetadata {
112 self.inner
113 }
114}
115
116impl ErrorMetadata {
117 pub fn code(&self) -> Option<&str> {
119 self.code.as_deref()
120 }
121 pub fn message(&self) -> Option<&str> {
123 self.message.as_deref()
124 }
125 pub fn extra(&self, key: &'static str) -> Option<&str> {
127 self.extras
128 .as_ref()
129 .and_then(|extras| extras.get(key).map(|k| k.as_str()))
130 }
131
132 pub fn builder() -> Builder {
134 Builder::default()
135 }
136
137 pub fn into_builder(self) -> Builder {
139 Builder { inner: self }
140 }
141}
142
143impl ProvideErrorKind for ErrorMetadata {
144 fn retryable_error_kind(&self) -> Option<ErrorKind> {
145 None
146 }
147
148 fn code(&self) -> Option<&str> {
149 ErrorMetadata::code(self)
150 }
151}
152
153impl fmt::Display for ErrorMetadata {
154 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
155 let mut fmt = f.debug_struct("Error");
156 if let Some(code) = &self.code {
157 fmt.field("code", code);
158 }
159 if let Some(message) = &self.message {
160 fmt.field("message", message);
161 }
162 if let Some(extras) = &self.extras {
163 for (k, v) in extras {
164 fmt.field(k, &v);
165 }
166 }
167 fmt.finish()
168 }
169}
170
171impl std::error::Error for ErrorMetadata {}