eng_units/units/
time_unit.rs

1// eng-units - engineering unit conversion and calculation library
2// Copyright (C) 2023 Frank Pereny
3
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with this program.  If not, see <https://www.gnu.org/licenses/>.
16
17use crate::units::AmountOfSubstanceUnit;
18use crate::units::ElectricCurrentUnit;
19use crate::units::IsEngUnitType;
20use crate::units::LengthUnit;
21use crate::units::LuminousIntensityUnit;
22use crate::units::MassUnit;
23use crate::units::TemperatureDeltaUnit;
24
25#[macro_export]
26macro_rules! time {
27    ($value:literal, $unit:expr) => {{
28        let mut unit = EngUnit::new();
29        unit.value = $value;
30        unit.time_count = 1;
31        if $unit == TimeUnit::None {
32            unit.time_count = 0;
33        }
34        unit.time_unit = $unit;
35        unit
36    }};
37}
38
39#[macro_export]
40macro_rules! s {
41    ($value:expr) => {{
42        let mut unit = EngUnit::new();
43        unit.value = $value;
44        unit.time_count = 1;
45        unit.time_unit = TimeUnit::Second;
46        unit
47    }};
48}
49
50#[derive(Copy, Clone, Debug, PartialEq)]
51pub enum TimeUnit {
52    Second,
53    Minute,
54    Hour,
55    None,
56}
57
58impl<
59        T: IsEngUnitType
60            + Into<AmountOfSubstanceUnit>
61            + Into<ElectricCurrentUnit>
62            + Into<LengthUnit>
63            + Into<LuminousIntensityUnit>
64            + Into<MassUnit>
65            + Into<TemperatureDeltaUnit>
66            + Into<TimeUnit>,
67    > From<&T> for TimeUnit
68{
69    fn from(value: &T) -> Self {
70        if T::is_amount_unit() {
71            value.into()
72        } else {
73            Self::None
74        }
75    }
76}
77impl IsEngUnitType for TimeUnit {
78    fn is_time_unit() -> bool {
79        true
80    }
81}
82impl From<AmountOfSubstanceUnit> for TimeUnit {
83    fn from(_: AmountOfSubstanceUnit) -> Self {
84        TimeUnit::None
85    }
86}
87impl From<ElectricCurrentUnit> for TimeUnit {
88    fn from(_: ElectricCurrentUnit) -> Self {
89        TimeUnit::None
90    }
91}
92impl From<LengthUnit> for TimeUnit {
93    fn from(_: LengthUnit) -> Self {
94        TimeUnit::None
95    }
96}
97impl From<LuminousIntensityUnit> for TimeUnit {
98    fn from(_: LuminousIntensityUnit) -> Self {
99        TimeUnit::None
100    }
101}
102impl From<MassUnit> for TimeUnit {
103    fn from(_: MassUnit) -> Self {
104        TimeUnit::None
105    }
106}
107impl From<TemperatureDeltaUnit> for TimeUnit {
108    fn from(_: TemperatureDeltaUnit) -> Self {
109        TimeUnit::None
110    }
111}
112
113pub const MINUTE_TO_SECONDS: f64 = 60.0;
114pub const HOUR_TO_SECONDS: f64 = 3600.0;
115pub const HOUR_TO_MINUTES: f64 = 60.0;
116
117impl TimeUnit {
118    pub fn to_string(&self) -> &'static str {
119        match self {
120            TimeUnit::Second => "s",
121            TimeUnit::Minute => "min",
122            TimeUnit::Hour => "hr",
123            TimeUnit::None => "",
124        }
125    }
126
127    pub fn conversion_factor(from: &TimeUnit, to: &TimeUnit) -> f64 {
128        match from {
129            TimeUnit::Second => match to {
130                TimeUnit::Second => 1.0,
131                TimeUnit::Minute => 1.0 / MINUTE_TO_SECONDS,
132                TimeUnit::Hour => 1.0 / HOUR_TO_SECONDS,
133                TimeUnit::None => 1.0,
134            },
135            TimeUnit::Minute => match to {
136                TimeUnit::Minute => 1.0,
137                TimeUnit::Second => MINUTE_TO_SECONDS,
138                TimeUnit::Hour => HOUR_TO_MINUTES,
139                TimeUnit::None => 1.0,
140            },
141            TimeUnit::Hour => match to {
142                TimeUnit::Minute => HOUR_TO_MINUTES,
143                TimeUnit::Second => HOUR_TO_SECONDS,
144                TimeUnit::Hour => 1.0,
145                TimeUnit::None => 1.0,
146            },
147            TimeUnit::None => 1.0,
148        }
149    }
150}