microcad_lang/value/quantity/
ops.rs

1// Copyright © 2025 The µcad authors <info@ucad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4//! Quantity binery operators module.
5
6use microcad_core::{Integer, Scalar};
7
8use crate::{ty::*, value::*};
9
10impl std::ops::Neg for Quantity {
11    type Output = Quantity;
12
13    fn neg(self) -> Self::Output {
14        Self {
15            value: -self.value,
16            quantity_type: self.quantity_type,
17        }
18    }
19}
20
21impl std::ops::Add for Quantity {
22    type Output = QuantityResult;
23
24    fn add(self, rhs: Self) -> Self::Output {
25        if self.quantity_type == rhs.quantity_type {
26            Ok(Quantity::new(self.value + rhs.value, self.quantity_type))
27        } else {
28            Err(QuantityError::InvalidOperation(self, '+', rhs))
29        }
30    }
31}
32
33impl std::ops::Add<Integer> for Quantity {
34    type Output = QuantityResult;
35
36    fn add(self, rhs: Integer) -> Self::Output {
37        if self.quantity_type == QuantityType::Scalar {
38            Ok(Quantity::new(
39                self.value + rhs as Scalar,
40                self.quantity_type,
41            ))
42        } else {
43            Err(QuantityError::InvalidOperation(self, '+', rhs.into()))
44        }
45    }
46}
47
48impl std::ops::Add<Quantity> for Integer {
49    type Output = QuantityResult;
50
51    fn add(self, rhs: Quantity) -> Self::Output {
52        if rhs.quantity_type == QuantityType::Scalar {
53            Ok(Quantity::new(self as Scalar + rhs.value, rhs.quantity_type))
54        } else {
55            Err(QuantityError::InvalidOperation(self.into(), '+', rhs))
56        }
57    }
58}
59
60impl std::ops::Sub for Quantity {
61    type Output = QuantityResult;
62
63    fn sub(self, rhs: Self) -> Self::Output {
64        if self.quantity_type == rhs.quantity_type {
65            Ok(Quantity::new(self.value - rhs.value, self.quantity_type))
66        } else {
67            Err(QuantityError::InvalidOperation(self, '-', rhs))
68        }
69    }
70}
71
72impl std::ops::Sub<Integer> for Quantity {
73    type Output = QuantityResult;
74
75    fn sub(self, rhs: Integer) -> Self::Output {
76        if self.quantity_type == QuantityType::Scalar {
77            Ok(Quantity::new(
78                self.value - rhs as Scalar,
79                self.quantity_type,
80            ))
81        } else {
82            Err(QuantityError::InvalidOperation(self, '-', rhs.into()))
83        }
84    }
85}
86
87impl std::ops::Sub<Quantity> for Integer {
88    type Output = QuantityResult;
89
90    fn sub(self, rhs: Quantity) -> Self::Output {
91        if rhs.quantity_type == QuantityType::Scalar {
92            Ok(Quantity::new(self as Scalar - rhs.value, rhs.quantity_type))
93        } else {
94            Err(QuantityError::InvalidOperation(self.into(), '-', rhs))
95        }
96    }
97}
98
99impl std::ops::Mul for Quantity {
100    type Output = QuantityResult;
101
102    fn mul(self, rhs: Self) -> Self::Output {
103        let t = self.quantity_type.clone() * rhs.quantity_type.clone();
104        if t == QuantityType::Invalid {
105            Err(QuantityError::InvalidOperation(self, '*', rhs))
106        } else {
107            Ok(Self::new(self.value * rhs.value, t))
108        }
109    }
110}
111
112impl std::ops::Mul<Integer> for Quantity {
113    type Output = QuantityResult;
114
115    fn mul(self, rhs: Integer) -> Self::Output {
116        self * Into::<Quantity>::into(rhs)
117    }
118}
119
120impl std::ops::Mul<Quantity> for Integer {
121    type Output = QuantityResult;
122
123    fn mul(self, rhs: Quantity) -> Self::Output {
124        Into::<Quantity>::into(self) * rhs
125    }
126}
127
128impl std::ops::Div for Quantity {
129    type Output = QuantityResult;
130
131    fn div(self, rhs: Self) -> Self::Output {
132        let t = self.quantity_type.clone() / rhs.quantity_type.clone();
133        if t == QuantityType::Invalid {
134            Err(QuantityError::InvalidOperation(self, '/', rhs))
135        } else {
136            Ok(Self::new(self.value / rhs.value, t))
137        }
138    }
139}
140
141impl std::ops::Div<Integer> for Quantity {
142    type Output = QuantityResult;
143
144    fn div(self, rhs: Integer) -> Self::Output {
145        self / Into::<Quantity>::into(rhs)
146    }
147}
148
149impl std::ops::Div<Quantity> for Integer {
150    type Output = QuantityResult;
151
152    fn div(self, rhs: Quantity) -> Self::Output {
153        Into::<Quantity>::into(self) / rhs
154    }
155}