1use std::error::Error as StdError;
21use std::fmt;
22use std::str::FromStr;
23
24use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize};
25use url::Url;
26
27pub(crate) mod helpers;
28
29pub mod event;
30pub mod event_type;
31pub mod misc;
32pub mod partition;
33pub mod publishing;
34pub mod subscription;
35
36new_type! {
37 #[doc="The base URL to the Nakadi API."]
38 #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
39 pub copy struct NakadiBaseUrl(Url, env="NAKADI_BASE_URL");
40}
41
42impl NakadiBaseUrl {
43 pub fn as_url(&self) -> &Url {
44 &self.0
45 }
46
47 pub fn as_str(&self) -> &str {
48 &self.0.as_ref()
49 }
50}
51
52impl AsRef<str> for NakadiBaseUrl {
53 fn as_ref(&self) -> &str {
54 self.as_str()
55 }
56}
57
58#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Serialize, Deserialize)]
63pub struct FlowId(String);
64
65impl FlowId {
66 pub fn new<T: Into<String>>(s: T) -> Self {
67 FlowId(s.into())
68 }
69
70 pub fn new_disp<T: fmt::Display>(s: T) -> Self {
71 FlowId(s.to_string())
72 }
73
74 pub fn as_str(&self) -> &str {
75 &self.0.as_ref()
76 }
77
78 pub fn into_inner(self) -> String {
79 self.0
80 }
81
82 pub fn random() -> Self {
83 FlowId(uuid::Uuid::new_v4().to_string())
84 }
85}
86
87#[derive(Debug, Clone, Copy)]
89pub struct RandomFlowId;
90
91impl From<RandomFlowId> for FlowId {
92 fn from(_: RandomFlowId) -> Self {
93 Self::random()
94 }
95}
96
97impl From<()> for FlowId {
98 fn from(_: ()) -> Self {
99 Self::random()
100 }
101}
102
103impl From<String> for FlowId {
104 fn from(v: String) -> Self {
105 Self::new(v)
106 }
107}
108
109impl From<&str> for FlowId {
110 fn from(v: &str) -> Self {
111 Self::new(v)
112 }
113}
114
115impl From<uuid::Uuid> for FlowId {
116 fn from(v: uuid::Uuid) -> Self {
117 Self::new(v.to_string())
118 }
119}
120
121impl fmt::Display for FlowId {
122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123 write!(f, "{}", self.0)
124 }
125}
126
127impl AsRef<str> for FlowId {
128 fn as_ref(&self) -> &str {
129 &self.0
130 }
131}
132
133impl FromStr for FlowId {
134 type Err = Error;
135
136 fn from_str(s: &str) -> Result<Self, Self::Err> {
137 Ok(FlowId::new(s))
138 }
139}
140
141#[derive(Debug)]
145pub struct Error {
146 message: Option<String>,
147 source: Option<Box<dyn StdError + Send + Sync + 'static>>,
148}
149
150impl Error {
151 pub fn new<T: fmt::Display>(msg: T) -> Self {
152 Self {
153 message: Some(msg.to_string()),
154 source: None,
155 }
156 }
157
158 pub fn from_error<E: StdError + Send + Sync + 'static>(err: E) -> Self {
159 Self {
160 message: None,
161 source: Some(Box::new(err)),
162 }
163 }
164
165 pub fn boxed(self) -> Box<dyn StdError + Send + 'static> {
166 Box::new(self)
167 }
168}
169
170impl fmt::Display for Error {
171 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172 match (self.message.as_ref(), self.source().as_ref()) {
173 (Some(msg), Some(err)) => write!(f, "{} - Caused by: {}", msg, err)?,
174 (Some(msg), _) => write!(f, "{}", msg)?,
175 (_, Some(err)) => write!(f, "An error occurred caused by: {}", err)?,
176 _ => write!(f, "some unspecified error occurred")?,
177 }
178
179 Ok(())
180 }
181}
182
183impl StdError for Error {
184 fn source(&self) -> Option<&(dyn StdError + 'static)> {
185 self.source.as_ref().map(|p| &**p as &dyn StdError)
186 }
187}
188
189impl From<serde_json::Error> for Error {
190 fn from(err: serde_json::Error) -> Self {
191 Self::new(err.to_string())
192 }
193}
194
195fn deserialize_empty_string_is_none<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
197where
198 D: Deserializer<'de>,
199 T: FromStr,
200 T::Err: std::fmt::Display,
201{
202 let s = String::deserialize(deserializer)?;
203 if s.is_empty() {
204 Ok(None)
205 } else {
206 let parsed = s
207 .parse::<T>()
208 .map_err(|err| SerdeError::custom(format!("deserialization error: {}", err)))?;
209 Ok(Some(parsed))
210 }
211}