1use std::ops::{Add, Div};
2
3use derive_deref::{Deref, DerefMut};
4use serde::{Serialize, Serializer, ser::SerializeTuple};
5use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
6
7use super::{Cents, Dollars, Sats};
8
9#[derive(Debug, Default, Clone, FromBytes, Immutable, IntoBytes, KnownLayout)]
10#[repr(C)]
11pub struct OHLCCents {
12 pub open: Open<Cents>,
13 pub high: High<Cents>,
14 pub low: Low<Cents>,
15 pub close: Close<Cents>,
16}
17
18impl From<(Open<Cents>, High<Cents>, Low<Cents>, Close<Cents>)> for OHLCCents {
19 fn from(value: (Open<Cents>, High<Cents>, Low<Cents>, Close<Cents>)) -> Self {
20 Self {
21 open: value.0,
22 high: value.1,
23 low: value.2,
24 close: value.3,
25 }
26 }
27}
28
29impl From<Close<Cents>> for OHLCCents {
30 fn from(value: Close<Cents>) -> Self {
31 Self {
32 open: Open::from(value),
33 high: High::from(value),
34 low: Low::from(value),
35 close: value,
36 }
37 }
38}
39
40impl Serialize for OHLCCents {
41 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
42 where
43 S: Serializer,
44 {
45 let mut tup = serializer.serialize_tuple(4)?;
46 tup.serialize_element(&self.open)?;
47 tup.serialize_element(&self.high)?;
48 tup.serialize_element(&self.low)?;
49 tup.serialize_element(&self.close)?;
50 tup.end()
51 }
52}
53
54#[derive(Debug, Default, Clone, FromBytes, Immutable, IntoBytes, KnownLayout)]
55#[repr(C)]
56pub struct OHLCDollars {
57 pub open: Open<Dollars>,
58 pub high: High<Dollars>,
59 pub low: Low<Dollars>,
60 pub close: Close<Dollars>,
61}
62
63impl Serialize for OHLCDollars {
64 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
65 where
66 S: Serializer,
67 {
68 let mut tup = serializer.serialize_tuple(4)?;
69 tup.serialize_element(&self.open)?;
70 tup.serialize_element(&self.high)?;
71 tup.serialize_element(&self.low)?;
72 tup.serialize_element(&self.close)?;
73 tup.end()
74 }
75}
76
77impl From<(Open<Dollars>, High<Dollars>, Low<Dollars>, Close<Dollars>)> for OHLCDollars {
78 fn from(value: (Open<Dollars>, High<Dollars>, Low<Dollars>, Close<Dollars>)) -> Self {
79 Self {
80 open: value.0,
81 high: value.1,
82 low: value.2,
83 close: value.3,
84 }
85 }
86}
87
88impl From<Close<Dollars>> for OHLCDollars {
89 fn from(value: Close<Dollars>) -> Self {
90 Self {
91 open: Open::from(value),
92 high: High::from(value),
93 low: Low::from(value),
94 close: value,
95 }
96 }
97}
98
99impl From<OHLCCents> for OHLCDollars {
100 fn from(value: OHLCCents) -> Self {
101 Self::from(&value)
102 }
103}
104
105impl From<&OHLCCents> for OHLCDollars {
106 fn from(value: &OHLCCents) -> Self {
107 Self {
108 open: value.open.into(),
109 high: value.high.into(),
110 low: value.low.into(),
111 close: value.close.into(),
112 }
113 }
114}
115
116#[derive(Debug, Default, Clone, FromBytes, Immutable, IntoBytes, KnownLayout)]
117#[repr(C)]
118pub struct OHLCSats {
119 pub open: Open<Sats>,
120 pub high: High<Sats>,
121 pub low: Low<Sats>,
122 pub close: Close<Sats>,
123}
124
125impl Serialize for OHLCSats {
126 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
127 where
128 S: Serializer,
129 {
130 let mut tup = serializer.serialize_tuple(4)?;
131 tup.serialize_element(&self.open)?;
132 tup.serialize_element(&self.high)?;
133 tup.serialize_element(&self.low)?;
134 tup.serialize_element(&self.close)?;
135 tup.end()
136 }
137}
138
139impl From<(Open<Sats>, High<Sats>, Low<Sats>, Close<Sats>)> for OHLCSats {
140 fn from(value: (Open<Sats>, High<Sats>, Low<Sats>, Close<Sats>)) -> Self {
141 Self {
142 open: value.0,
143 high: value.1,
144 low: value.2,
145 close: value.3,
146 }
147 }
148}
149
150impl From<Close<Sats>> for OHLCSats {
151 fn from(value: Close<Sats>) -> Self {
152 Self {
153 open: Open::from(value),
154 high: High::from(value),
155 low: Low::from(value),
156 close: value,
157 }
158 }
159}
160
161#[derive(
162 Debug,
163 Default,
164 Clone,
165 Copy,
166 PartialEq,
167 Eq,
168 PartialOrd,
169 Ord,
170 FromBytes,
171 Immutable,
172 IntoBytes,
173 KnownLayout,
174 Deref,
175 DerefMut,
176 Serialize,
177)]
178#[repr(C)]
179pub struct Open<T>(T);
180
181impl<T> Open<T> {
182 pub fn new(value: T) -> Self {
183 Self(value)
184 }
185}
186
187impl<T> From<usize> for Open<T>
188where
189 T: From<usize>,
190{
191 fn from(value: usize) -> Self {
192 Self(T::from(value))
193 }
194}
195
196impl<T> From<f64> for Open<T>
197where
198 T: From<f64>,
199{
200 fn from(value: f64) -> Self {
201 Self(T::from(value))
202 }
203}
204
205impl<T> From<Open<T>> for f64
206where
207 f64: From<T>,
208{
209 fn from(value: Open<T>) -> Self {
210 Self::from(value.0)
211 }
212}
213
214impl<T> From<Close<T>> for Open<T>
215where
216 T: Copy,
217{
218 fn from(value: Close<T>) -> Self {
219 Self(*value)
220 }
221}
222
223impl From<Open<Cents>> for Open<Dollars> {
224 fn from(value: Open<Cents>) -> Self {
225 Self(Dollars::from(*value))
226 }
227}
228
229impl<T> Add for Open<T>
230where
231 T: Add<Output = T>,
232{
233 type Output = Self;
234 fn add(self, rhs: Self) -> Self::Output {
235 Self(self.0 + rhs.0)
236 }
237}
238
239impl<T> Div<usize> for Open<T>
240where
241 T: Div<usize, Output = T>,
242{
243 type Output = Self;
244 fn div(self, rhs: usize) -> Self::Output {
245 Self(self.0 / rhs)
246 }
247}
248
249#[derive(
250 Debug,
251 Default,
252 PartialEq,
253 Eq,
254 PartialOrd,
255 Ord,
256 Clone,
257 Copy,
258 FromBytes,
259 Immutable,
260 IntoBytes,
261 KnownLayout,
262 Deref,
263 DerefMut,
264 Serialize,
265)]
266#[repr(C)]
267pub struct High<T>(T);
268
269impl<T> High<T> {
270 pub fn new(value: T) -> Self {
271 Self(value)
272 }
273}
274
275impl<T> From<usize> for High<T>
276where
277 T: From<usize>,
278{
279 fn from(value: usize) -> Self {
280 Self(T::from(value))
281 }
282}
283
284impl<T> From<f64> for High<T>
285where
286 T: From<f64>,
287{
288 fn from(value: f64) -> Self {
289 Self(T::from(value))
290 }
291}
292
293impl<T> From<High<T>> for f64
294where
295 f64: From<T>,
296{
297 fn from(value: High<T>) -> Self {
298 Self::from(value.0)
299 }
300}
301
302impl<T> From<Close<T>> for High<T>
303where
304 T: Copy,
305{
306 fn from(value: Close<T>) -> Self {
307 Self(*value)
308 }
309}
310
311impl From<High<Cents>> for High<Dollars> {
312 fn from(value: High<Cents>) -> Self {
313 Self(Dollars::from(*value))
314 }
315}
316
317impl<T> Add for High<T>
318where
319 T: Add<Output = T>,
320{
321 type Output = Self;
322 fn add(self, rhs: Self) -> Self::Output {
323 Self(self.0 + rhs.0)
324 }
325}
326
327impl<T> Div<usize> for High<T>
328where
329 T: Div<usize, Output = T>,
330{
331 type Output = Self;
332 fn div(self, rhs: usize) -> Self::Output {
333 Self(self.0 / rhs)
334 }
335}
336
337#[derive(
338 Debug,
339 Default,
340 Clone,
341 Copy,
342 PartialEq,
343 Eq,
344 PartialOrd,
345 Ord,
346 FromBytes,
347 Immutable,
348 IntoBytes,
349 KnownLayout,
350 Deref,
351 DerefMut,
352 Serialize,
353)]
354#[repr(C)]
355pub struct Low<T>(T);
356
357impl<T> Low<T> {
358 pub fn new(value: T) -> Self {
359 Self(value)
360 }
361}
362
363impl<T> From<usize> for Low<T>
364where
365 T: From<usize>,
366{
367 fn from(value: usize) -> Self {
368 Self(T::from(value))
369 }
370}
371
372impl<T> From<f64> for Low<T>
373where
374 T: From<f64>,
375{
376 fn from(value: f64) -> Self {
377 Self(T::from(value))
378 }
379}
380
381impl<T> From<Low<T>> for f64
382where
383 f64: From<T>,
384{
385 fn from(value: Low<T>) -> Self {
386 Self::from(value.0)
387 }
388}
389
390impl<T> From<Close<T>> for Low<T>
391where
392 T: Copy,
393{
394 fn from(value: Close<T>) -> Self {
395 Self(*value)
396 }
397}
398
399impl From<Low<Cents>> for Low<Dollars> {
400 fn from(value: Low<Cents>) -> Self {
401 Self(Dollars::from(*value))
402 }
403}
404
405impl<T> Add for Low<T>
406where
407 T: Add<Output = T>,
408{
409 type Output = Self;
410 fn add(self, rhs: Self) -> Self::Output {
411 Self(self.0 + rhs.0)
412 }
413}
414
415impl<T> Div<usize> for Low<T>
416where
417 T: Div<usize, Output = T>,
418{
419 type Output = Self;
420 fn div(self, rhs: usize) -> Self::Output {
421 Self(self.0 / rhs)
422 }
423}
424
425#[derive(
426 Debug,
427 Default,
428 Clone,
429 Copy,
430 PartialEq,
431 Eq,
432 PartialOrd,
433 Ord,
434 FromBytes,
435 Immutable,
436 IntoBytes,
437 KnownLayout,
438 Deref,
439 DerefMut,
440 Serialize,
441)]
442#[repr(C)]
443pub struct Close<T>(T);
444
445impl<T> Close<T> {
446 pub fn new(value: T) -> Self {
447 Self(value)
448 }
449}
450
451impl<T> From<usize> for Close<T>
452where
453 T: From<usize>,
454{
455 fn from(value: usize) -> Self {
456 Self(T::from(value))
457 }
458}
459
460impl<T> From<f32> for Close<T>
461where
462 T: From<f32>,
463{
464 fn from(value: f32) -> Self {
465 Self(T::from(value))
466 }
467}
468
469impl<T> From<f64> for Close<T>
470where
471 T: From<f64>,
472{
473 fn from(value: f64) -> Self {
474 Self(T::from(value))
475 }
476}
477
478impl<T> From<Close<T>> for f32
479where
480 f32: From<T>,
481{
482 fn from(value: Close<T>) -> Self {
483 Self::from(value.0)
484 }
485}
486
487impl<T> From<Close<T>> for f64
488where
489 f64: From<T>,
490{
491 fn from(value: Close<T>) -> Self {
492 Self::from(value.0)
493 }
494}
495
496impl From<Close<Cents>> for Close<Dollars> {
503 fn from(value: Close<Cents>) -> Self {
504 Self(Dollars::from(*value))
505 }
506}
507
508impl<T> Add for Close<T>
509where
510 T: Add<Output = T>,
511{
512 type Output = Self;
513 fn add(self, rhs: Self) -> Self::Output {
514 Self(self.0 + rhs.0)
515 }
516}
517
518impl<T> Div<usize> for Close<T>
519where
520 T: Div<usize, Output = T>,
521{
522 type Output = Self;
523 fn div(self, rhs: usize) -> Self::Output {
524 Self(self.0 / rhs)
525 }
526}
527
528