Skip to content

Commit 0d3016b

Browse files
committed
Use macros to implement fmt::Display.
1 parent bb9481d commit 0d3016b

File tree

7 files changed

+73
-47
lines changed

7 files changed

+73
-47
lines changed

examples/format_test.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,10 @@ use measurements::Volume;
66
fn main() {
77
let t = Temperature::from_celsius(123.456);
88
let d = Length::from_meters(123.456);
9-
let p = Pressure::from_pascals(123.456);
10-
let v = Volume::from_cubic_meters(123.456);
9+
let p = Pressure::from_millibars(123.456);
10+
let v = Volume::from_litres(123.456);
1111
println!("Temp of {0:.5} outside", t);
12-
println!("Temp of {0:.5} C outside", t.as_celsius());
1312
println!("Distance of {0:.5}", d);
14-
println!("Distance of {0:.5} m", d.as_meters());
1513
println!("Pressure of {0:.5}", p);
16-
println!("Pressure of {0:.5} Pa", p.as_pascals());
1714
println!("Volume of {0:.5}", v);
18-
println!("Volume of {0:.5} m3", v.as_cubic_meters());
1915
}

src/length.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -151,14 +151,11 @@ impl Measurement for Length {
151151
fn from_base_units(units: f64) -> Self {
152152
Self::from_meters(units)
153153
}
154+
155+
fn get_base_units_name(&self) -> &'static str {
156+
"m"
157+
}
154158
}
155159

156160
implement_measurement! { Length }
157161

158-
impl ::std::fmt::Display for Length {
159-
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
160-
let p = f.precision().unwrap_or(1);
161-
let w = f.width().unwrap_or(0);
162-
write!(f, "{value:width$.prec$}\u{00A0}m", prec=p, width=w, value=self.as_meters())
163-
}
164-
}

src/measurement.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
/// fn from_base_units(units: f64) -> Self {
2222
/// Cubits { forearms: units }
2323
/// }
24+
///
25+
/// fn get_base_units_name(&self) -> &'static str {
26+
/// "cu"
27+
/// }
2428
/// }
2529
///
2630
/// // Invoke the macro to automatically implement Add, Sub, etc...
@@ -31,15 +35,43 @@
3135
/// fn main() { }
3236
/// ```
3337
pub trait Measurement {
38+
fn get_appropriate_units_name(&self) -> &'static str {
39+
self.get_base_units_name()
40+
}
41+
fn get_appropriate_units(&self) -> f64 {
42+
self.get_base_units()
43+
}
44+
fn get_base_units_name(&self) -> &'static str;
3445
fn get_base_units(&self) -> f64;
3546
fn from_base_units(units: f64) -> Self;
3647
}
3748

49+
/// This is a special macro that creates the code to implement
50+
/// std::fmt::Display.
51+
#[macro_export]
52+
macro_rules! implement_display {
53+
($($t:ty)*) => ($(
54+
55+
impl ::std::fmt::Display for $t {
56+
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
57+
let p = f.precision().unwrap_or(1);
58+
let w = f.width().unwrap_or(0);
59+
write!(f, "{value:width$.prec$}\u{00A0}{unit}",
60+
prec=p, width=w, value=self.get_appropriate_units(), unit=self.get_appropriate_units_name())
61+
}
62+
}
63+
)*)
64+
}
65+
66+
3867
/// This is a special macro that creates the code to implement
3968
/// operator and comparison overrides.
4069
#[macro_export]
4170
macro_rules! implement_measurement {
4271
($($t:ty)*) => ($(
72+
73+
implement_display!( $t );
74+
4375
impl ::std::ops::Add for $t {
4476
type Output = Self;
4577

src/pressure.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,11 @@ impl Measurement for Pressure {
8383
fn from_base_units(units: f64) -> Self {
8484
Self::from_millibars(units)
8585
}
86+
87+
fn get_base_units_name(&self) -> &'static str {
88+
"mbar"
89+
}
8690
}
8791

8892
implement_measurement! { Pressure }
8993

90-
impl ::std::fmt::Display for Pressure {
91-
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
92-
let p = f.precision().unwrap_or(1);
93-
let w = f.width().unwrap_or(0);
94-
write!(f, "{value:width$.prec$}\u{00A0}Pa", prec=p, width=w, value=self.as_pascals())
95-
}
96-
}

src/temperature.rs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,25 @@ impl Measurement for Temperature {
110110
fn from_base_units(degrees_kelvin: f64) -> Self {
111111
Self::from_kelvin(degrees_kelvin)
112112
}
113+
114+
fn get_base_units_name(&self) -> &'static str {
115+
"K"
116+
}
117+
118+
}
119+
120+
impl Measurement for TemperatureDelta {
121+
fn get_base_units(&self) -> f64 {
122+
self.kelvin_degrees
123+
}
124+
125+
fn from_base_units(kelvin_degrees: f64) -> Self {
126+
Self::from_kelvin(kelvin_degrees)
127+
}
128+
129+
fn get_base_units_name(&self) -> &'static str {
130+
"K"
131+
}
113132
}
114133

115134
impl ::std::ops::Add<TemperatureDelta> for Temperature {
@@ -162,18 +181,5 @@ impl ::std::cmp::PartialOrd for TemperatureDelta {
162181
}
163182
}
164183

165-
impl ::std::fmt::Display for Temperature {
166-
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
167-
let p = f.precision().unwrap_or(1);
168-
let w = f.width().unwrap_or(0);
169-
write!(f, "{temp:width$.prec$}\u{00A0}\u{00B0}C", prec=p, width=w, temp=self.as_celsius())
170-
}
171-
}
172-
173-
impl ::std::fmt::Display for TemperatureDelta {
174-
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
175-
let p = f.precision().unwrap_or(1);
176-
let w = f.width().unwrap_or(0);
177-
write!(f, "{temp:width$.prec$}\u{00A0}\u{00B0}C", prec=p, width=w, temp=self.as_celsius())
178-
}
179-
}
184+
implement_display!( Temperature );
185+
implement_display!( TemperatureDelta );

src/volume.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -205,14 +205,12 @@ impl Measurement for Volume {
205205
fn from_base_units(units: f64) -> Self {
206206
Self::from_litres(units)
207207
}
208+
209+
fn get_base_units_name(&self) -> &'static str {
210+
"l"
211+
}
212+
208213
}
209214

210215
implement_measurement! { Volume }
211216

212-
impl ::std::fmt::Display for Volume {
213-
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
214-
let p = f.precision().unwrap_or(1);
215-
let w = f.width().unwrap_or(0);
216-
write!(f, "{volume:width$.prec$}\u{00A0}m\u{00B3}", prec=p, width=w, volume=self.as_cubic_meters())
217-
}
218-
}

src/weight.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,12 @@ impl Measurement for Weight {
151151
fn from_base_units(units: f64) -> Self {
152152
Self::from_kilograms(units)
153153
}
154+
155+
fn get_base_units_name(&self) -> &'static str {
156+
"kg"
157+
}
158+
154159
}
155160

156161
implement_measurement! { Weight }
157162

158-
impl ::std::fmt::Display for Weight {
159-
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
160-
write!(f, "{:.1} kg", self.as_kilograms())
161-
}
162-
}

0 commit comments

Comments
 (0)