1use rusty_common::SmartString;
7use serde::{Deserialize, Serialize};
8use std::{fmt, str::FromStr};
9use uuid::Uuid;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
13#[serde(transparent)]
14pub struct OrderId(pub Uuid);
15
16impl OrderId {
17 #[inline]
19 #[must_use]
20 #[allow(clippy::new_without_default)] pub fn new() -> Self {
22 Self(Uuid::new_v4())
23 }
24
25 #[inline]
27 #[must_use]
28 pub const fn from_uuid(id: Uuid) -> Self {
29 Self(id)
30 }
31
32 #[inline]
34 #[must_use]
35 pub const fn as_uuid(&self) -> &Uuid {
36 &self.0
37 }
38
39 #[inline]
41 #[must_use]
42 pub const fn into_uuid(self) -> Uuid {
43 self.0
44 }
45}
46
47#[cfg(test)]
51impl OrderId {
52 #[must_use]
65 pub fn for_testing() -> Self {
66 Self(Uuid::nil())
67 }
68}
69
70impl fmt::Display for OrderId {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 write!(f, "{}", self.0)
73 }
74}
75
76impl From<Uuid> for OrderId {
77 fn from(id: Uuid) -> Self {
78 Self(id)
79 }
80}
81
82impl From<OrderId> for Uuid {
83 fn from(id: OrderId) -> Self {
84 id.0
85 }
86}
87
88#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
90#[serde(transparent)]
91pub struct TradeId(pub Uuid);
92
93impl TradeId {
94 #[inline]
96 #[must_use]
97 #[allow(clippy::new_without_default)] pub fn new() -> Self {
99 Self(Uuid::new_v4())
100 }
101
102 #[inline]
104 #[must_use]
105 pub const fn from_uuid(id: Uuid) -> Self {
106 Self(id)
107 }
108
109 #[inline]
111 #[must_use]
112 pub const fn as_uuid(&self) -> &Uuid {
113 &self.0
114 }
115
116 #[inline]
118 #[must_use]
119 pub const fn into_uuid(self) -> Uuid {
120 self.0
121 }
122}
123
124#[cfg(test)]
128impl TradeId {
129 #[must_use]
142 pub fn for_testing() -> Self {
143 Self(Uuid::nil())
144 }
145}
146
147impl fmt::Display for TradeId {
148 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
149 write!(f, "{}", self.0)
150 }
151}
152
153impl From<Uuid> for TradeId {
154 fn from(id: Uuid) -> Self {
155 Self(id)
156 }
157}
158
159impl From<TradeId> for Uuid {
160 fn from(id: TradeId) -> Self {
161 id.0
162 }
163}
164
165#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
167#[serde(transparent)]
168pub struct PositionId(pub Uuid);
169
170impl PositionId {
171 #[inline]
173 #[must_use]
174 #[allow(clippy::new_without_default)] pub fn new() -> Self {
176 Self(Uuid::new_v4())
177 }
178
179 #[inline]
181 #[must_use]
182 pub const fn from_uuid(id: Uuid) -> Self {
183 Self(id)
184 }
185
186 #[inline]
188 #[must_use]
189 pub const fn as_uuid(&self) -> &Uuid {
190 &self.0
191 }
192
193 #[inline]
195 #[must_use]
196 pub const fn into_uuid(self) -> Uuid {
197 self.0
198 }
199}
200
201#[cfg(test)]
205impl PositionId {
206 #[must_use]
219 pub fn for_testing() -> Self {
220 Self(Uuid::nil())
221 }
222}
223
224impl fmt::Display for PositionId {
225 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
226 write!(f, "{}", self.0)
227 }
228}
229
230impl From<Uuid> for PositionId {
231 fn from(id: Uuid) -> Self {
232 Self(id)
233 }
234}
235
236impl From<PositionId> for Uuid {
237 fn from(id: PositionId) -> Self {
238 id.0
239 }
240}
241
242#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
244pub struct StrategyId(pub SmartString);
245
246impl StrategyId {
247 #[inline]
249 #[must_use]
250 pub fn new(id: impl AsRef<str>) -> Self {
251 Self(id.as_ref().into())
252 }
253
254 #[inline]
256 #[must_use]
257 pub fn from_string(id: &str) -> Self {
258 Self(id.into())
259 }
260
261 #[inline]
263 #[must_use]
264 pub fn as_str(&self) -> &str {
265 self.0.as_str()
266 }
267
268 #[inline]
270 #[must_use]
271 pub fn into_smart_string(self) -> SmartString {
272 self.0
273 }
274}
275
276impl fmt::Display for StrategyId {
277 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
278 write!(f, "{}", self.0)
279 }
280}
281
282impl From<SmartString> for StrategyId {
283 fn from(id: SmartString) -> Self {
284 Self(id)
285 }
286}
287
288impl From<&str> for StrategyId {
289 fn from(id: &str) -> Self {
290 Self(id.into())
291 }
292}
293
294impl From<StrategyId> for SmartString {
295 fn from(id: StrategyId) -> Self {
296 id.0
297 }
298}
299
300impl FromStr for StrategyId {
301 type Err = std::convert::Infallible;
302
303 fn from_str(s: &str) -> Result<Self, Self::Err> {
304 Ok(Self(s.into()))
305 }
306}
307
308#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
310pub struct ClientId(pub SmartString);
311
312impl ClientId {
313 #[inline]
315 #[must_use]
316 pub fn new(id: impl AsRef<str>) -> Self {
317 Self(id.as_ref().into())
318 }
319
320 #[inline]
322 #[must_use]
323 pub fn from_string(id: &str) -> Self {
324 Self(id.into())
325 }
326
327 #[inline]
329 #[must_use]
330 pub fn as_str(&self) -> &str {
331 self.0.as_str()
332 }
333
334 #[inline]
336 #[must_use]
337 pub fn into_smart_string(self) -> SmartString {
338 self.0
339 }
340}
341
342impl fmt::Display for ClientId {
343 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
344 write!(f, "{}", self.0)
345 }
346}
347
348impl From<SmartString> for ClientId {
349 fn from(id: SmartString) -> Self {
350 Self(id)
351 }
352}
353
354impl From<&str> for ClientId {
355 fn from(id: &str) -> Self {
356 Self(id.into())
357 }
358}
359
360impl From<ClientId> for SmartString {
361 fn from(id: ClientId) -> Self {
362 id.0
363 }
364}
365
366impl FromStr for ClientId {
367 type Err = std::convert::Infallible;
368
369 fn from_str(s: &str) -> Result<Self, Self::Err> {
370 Ok(Self(s.into()))
371 }
372}
373
374#[cfg(test)]
375mod tests {
376 use super::*;
377
378 #[test]
379 fn test_order_id_for_testing() {
380 let test_id = OrderId::for_testing();
381 assert_eq!(test_id.to_string(), "00000000-0000-0000-0000-000000000000");
382 assert_eq!(test_id.as_uuid(), &Uuid::nil());
383 }
384
385 #[test]
386 fn test_trade_id_for_testing() {
387 let test_id = TradeId::for_testing();
388 assert_eq!(test_id.to_string(), "00000000-0000-0000-0000-000000000000");
389 assert_eq!(test_id.as_uuid(), &Uuid::nil());
390 }
391
392 #[test]
393 fn test_position_id_for_testing() {
394 let test_id = PositionId::for_testing();
395 assert_eq!(test_id.to_string(), "00000000-0000-0000-0000-000000000000");
396 assert_eq!(test_id.as_uuid(), &Uuid::nil());
397 }
398
399 #[test]
400 fn test_production_ids_are_different() {
401 let id1 = OrderId::new();
402 let id2 = OrderId::new();
403 assert_ne!(id1, id2);
404 assert_ne!(id1.to_string(), "00000000-0000-0000-0000-000000000000");
405 assert_ne!(id2.to_string(), "00000000-0000-0000-0000-000000000000");
406 }
407}