cas_unit_convert/convert.rs
1//! Provides the [`Convert`] trait, which is implemented by all [`Unit`]s.
2
3use super::unit::Unit;
4
5/// A trait implemented by all [`Unit`], providing the information needed to convert between them.
6pub trait Convert {
7 /// The base unit of this unit.
8 ///
9 /// The base unit is the unit in which conversions to other units of the same quantity are
10 /// defined. For example, the base unit of length is the meter, and the base unit of volume
11 /// is the cubic meter. It isn't particularly important which unit is chosen as the base
12 /// unit, as long as conversions between each unit and the base unit are correctly defined.
13 ///
14 /// In some cases, the choice of base unit may affect the precision of conversions. For
15 /// example, metric and customary units often don't have exact conversions between them. If the
16 /// base unit is chosen to be a metric unit, then conversions between customary units will
17 /// be done by converting to the metric base unit, and then to the target customary unit, which
18 /// is where the precision loss can occur.
19 const BASE: Self;
20
21 /// Returns the conversion factor from `&self` to [`Convert::BASE`], i.e. the value to multiply
22 /// a quantity in this unit by, in order to get a quantity in [`Convert::BASE`]. If the `self`
23 /// unit is the same as this unit, then this function should return `1.0`.
24 ///
25 /// For example, if [`Convert::BASE`] is the meter, the conversion factor for a centimeter
26 /// would be `0.01`.
27 fn conversion_factor(&self) -> f64;
28
29 /// Defines the conversion factor from [`Convert::BASE`], to a base unit that [`Convert::BASE`]
30 /// is derived from. Returns [`None`] if there is no conversion factor, meaning the two units
31 /// are unrelated.
32 ///
33 /// For example, [`Volume`] is derived from [`Length`] units cubed. The base unit for
34 /// [`Length`] is defined to be [`Length::Meter`]. So, this function should be manually
35 /// implemented for [`Volume`], and it should return the value to multiply by to convert from
36 /// `Volume::?` to cubic meters.
37 ///
38 /// [`Volume`]: super::Volume
39 /// [`Length`]: super::Length
40 /// [`Length::Meter`]: super::Length::Meter
41 fn conversion_factor_to(&self, _: impl Into<Unit>) -> Option<f64> {
42 None
43 }
44}