euphony_core/time/
compound.rs1use crate::time::{beat::Beat, measure::Measure, time_signature::TimeSignature};
2use core::ops::{Add, AddAssign, Mul, Sub, SubAssign};
3
4#[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd, Eq, Ord, Hash)]
5pub struct CompoundDuration {
6 pub measure: Measure,
7 pub beat: Beat,
8}
9
10macro_rules! compound_conversion {
11 ($ty:ident, $field:ident, $other_ty:ident, $other_field:ident) => {
12 impl From<$ty> for CompoundDuration {
13 fn from($field: $ty) -> Self {
14 Self {
15 $other_field: Default::default(),
16 $field,
17 }
18 }
19 }
20
21 impl Add<$ty> for CompoundDuration {
22 type Output = CompoundDuration;
23
24 fn add(self, $field: $ty) -> Self::Output {
25 CompoundDuration {
26 $field: self.$field + $field,
27 $other_field: self.$other_field,
28 }
29 }
30 }
31
32 impl AddAssign<$ty> for CompoundDuration {
33 fn add_assign(&mut self, $field: $ty) {
34 self.$field += $field;
35 }
36 }
37
38 impl Sub<$ty> for CompoundDuration {
39 type Output = CompoundDuration;
40
41 fn sub(self, $field: $ty) -> Self::Output {
42 CompoundDuration {
43 $field: self.$field - $field,
44 $other_field: self.$other_field,
45 }
46 }
47 }
48
49 impl SubAssign<$ty> for CompoundDuration {
50 fn sub_assign(&mut self, $field: $ty) {
51 self.$field -= $field;
52 }
53 }
54
55 impl Add<$ty> for $other_ty {
56 type Output = CompoundDuration;
57
58 fn add(self, value: $ty) -> Self::Output {
59 let compound: CompoundDuration = self.into();
60 compound + value
61 }
62 }
63
64 impl Sub<$ty> for $other_ty {
65 type Output = CompoundDuration;
66
67 fn sub(self, value: $ty) -> Self::Output {
68 let compound: CompoundDuration = self.into();
69 compound - value
70 }
71 }
72 };
73}
74
75compound_conversion!(Beat, beat, Measure, measure);
76compound_conversion!(Measure, measure, Beat, beat);
77
78impl Mul<TimeSignature> for CompoundDuration {
79 type Output = Beat;
80
81 fn mul(self, time_signature: TimeSignature) -> Self::Output {
82 self.beat * time_signature + self.measure * time_signature
83 }
84}