1use crate::{Quantity, Unit};
26use qtty_derive::Unit;
27
28pub use crate::dimension::Area;
30
31pub trait AreaUnit: Unit<Dim = Area> {}
33impl<T: Unit<Dim = Area>> AreaUnit for T {}
34
35#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
41#[unit(symbol = "m²", dimension = Area, ratio = 1.0)]
42pub struct SquareMeter;
43pub type SquareMeters = Quantity<SquareMeter>;
45
46#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
48#[unit(symbol = "km²", dimension = Area, ratio = 1e6)]
49pub struct SquareKilometer;
50pub type SquareKilometers = Quantity<SquareKilometer>;
52
53#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
55#[unit(symbol = "cm²", dimension = Area, ratio = 1e-4)]
56pub struct SquareCentimeter;
57pub type SquareCentimeters = Quantity<SquareCentimeter>;
59
60#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
62#[unit(symbol = "mm²", dimension = Area, ratio = 1e-6)]
63pub struct SquareMillimeter;
64pub type SquareMillimeters = Quantity<SquareMillimeter>;
66
67#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
73#[unit(symbol = "ha", dimension = Area, ratio = 1e4)]
74pub struct Hectare;
75pub type Hectares = Quantity<Hectare>;
77
78#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
80#[unit(symbol = "a", dimension = Area, ratio = 100.0)]
81pub struct Are;
82pub type Ares = Quantity<Are>;
84
85#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
91#[unit(symbol = "in²", dimension = Area, ratio = 6.4516e-4)]
92pub struct SquareInch;
93pub type SquareInches = Quantity<SquareInch>;
95
96#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
98#[unit(symbol = "ft²", dimension = Area, ratio = 0.09290304)]
99pub struct SquareFoot;
100pub type SquareFeet = Quantity<SquareFoot>;
102
103#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
105#[unit(symbol = "yd²", dimension = Area, ratio = 0.83612736)]
106pub struct SquareYard;
107pub type SquareYards = Quantity<SquareYard>;
109
110#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
112#[unit(symbol = "mi²", dimension = Area, ratio = 2_589_988.110_336)]
113pub struct SquareMile;
114pub type SquareMiles = Quantity<SquareMile>;
116
117#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
119#[unit(symbol = "ac", dimension = Area, ratio = 4_046.856_422_4)]
120pub struct Acre;
121pub type Acres = Quantity<Acre>;
123
124#[cfg(test)]
125mod tests {
126 use super::*;
127 use approx::assert_abs_diff_eq;
128
129 #[test]
130 fn sqm_to_sqkm() {
131 let a = SquareMeters::new(1_000_000.0);
132 let b: SquareKilometers = a.to();
133 assert_abs_diff_eq!(b.value(), 1.0, epsilon = 1e-12);
134 }
135
136 #[test]
137 fn hectare_to_sqm() {
138 let a = Hectares::new(1.0);
139 let b: SquareMeters = a.to();
140 assert_abs_diff_eq!(b.value(), 10_000.0, epsilon = 1e-9);
141 }
142
143 #[test]
144 fn acre_to_hectare() {
145 let a = Acres::new(1.0);
146 let b: Hectares = a.to();
147 assert_abs_diff_eq!(b.value(), 0.404_685_642_24, epsilon = 1e-9);
148 }
149
150 #[test]
151 fn sqft_to_sqm() {
152 let a = SquareFeet::new(1.0);
153 let b: SquareMeters = a.to();
154 assert_abs_diff_eq!(b.value(), 0.092_903_04, epsilon = 1e-9);
155 }
156
157 #[test]
158 fn length_product_to_area() {
159 use crate::length::{Meter, Meters};
160 use crate::Prod;
161
162 let side = Meters::new(5.0);
163 let area_prod: Quantity<Prod<Meter, Meter>> = side * side;
164 let area: SquareMeters = area_prod.to();
165 assert_abs_diff_eq!(area.value(), 25.0, epsilon = 1e-12);
166 }
167
168 #[test]
169 fn sqmile_to_sqkm() {
170 let a = SquareMiles::new(1.0);
171 let b: SquareKilometers = a.to();
172 assert_abs_diff_eq!(b.value(), 2.589_988_110_336, epsilon = 1e-6);
173 }
174}