1 //! A big dictionary of units and their conversion ratios.
2 //!
3 //! Arbitrary precision is retained.
4 
5 use std::{collections::HashMap, f64::consts::PI};
6 
7 use num_traits::One;
8 use once_cell::sync::Lazy;
9 
10 use crate::{unit::Unit, value::Number};
11 
12 pub(crate) static UNIT_CONVERSION_TABLE: Lazy<HashMap<Unit, HashMap<Unit, Number>>> =
13     Lazy::new(|| {
14         let mut from_in = HashMap::new();
15         from_in.insert(Unit::In, Number::one());
16         from_in.insert(Unit::Cm, Number::one() / Number::from(2.54));
17         from_in.insert(Unit::Pc, Number::small_ratio(1, 6));
18         from_in.insert(Unit::Mm, Number::one() / Number::from(25.4));
19         from_in.insert(Unit::Q, Number::one() / Number::from(101.6));
20         from_in.insert(Unit::Pt, Number::small_ratio(1, 72));
21         from_in.insert(Unit::Px, Number::small_ratio(1, 96));
22 
23         let mut from_cm = HashMap::new();
24         from_cm.insert(Unit::In, Number::from(2.54));
25         from_cm.insert(Unit::Cm, Number::one());
26         from_cm.insert(Unit::Pc, Number::from(2.54) / Number::from(6));
27         from_cm.insert(Unit::Mm, Number::small_ratio(1, 10));
28         from_cm.insert(Unit::Q, Number::small_ratio(1, 40));
29         from_cm.insert(Unit::Pt, Number::from(2.54) / Number::from(72));
30         from_cm.insert(Unit::Px, Number::from(2.54) / Number::from(96));
31 
32         let mut from_pc = HashMap::new();
33         from_pc.insert(Unit::In, Number::from(6));
34         from_pc.insert(Unit::Cm, Number::from(6) / Number::from(2.54));
35         from_pc.insert(Unit::Pc, Number::one());
36         from_pc.insert(Unit::Mm, Number::from(6) / Number::from(25.4));
37         from_pc.insert(Unit::Q, Number::from(6) / Number::from(101.6));
38         from_pc.insert(Unit::Pt, Number::small_ratio(1, 12));
39         from_pc.insert(Unit::Px, Number::small_ratio(1, 16));
40 
41         let mut from_mm = HashMap::new();
42         from_mm.insert(Unit::In, Number::from(25.4));
43         from_mm.insert(Unit::Cm, Number::from(10));
44         from_mm.insert(Unit::Pc, Number::from(25.4) / Number::from(6));
45         from_mm.insert(Unit::Mm, Number::one());
46         from_mm.insert(Unit::Q, Number::small_ratio(1, 4));
47         from_mm.insert(Unit::Pt, Number::from(25.4) / Number::from(72));
48         from_mm.insert(Unit::Px, Number::from(25.4) / Number::from(96));
49 
50         let mut from_q = HashMap::new();
51         from_q.insert(Unit::In, Number::from(101.6));
52         from_q.insert(Unit::Cm, Number::from(40));
53         from_q.insert(Unit::Pc, Number::from(101.6) / Number::from(6));
54         from_q.insert(Unit::Mm, Number::from(4));
55         from_q.insert(Unit::Q, Number::one());
56         from_q.insert(Unit::Pt, Number::from(101.6) / Number::from(72));
57         from_q.insert(Unit::Px, Number::from(101.6) / Number::from(96));
58 
59         let mut from_pt = HashMap::new();
60         from_pt.insert(Unit::In, Number::from(72));
61         from_pt.insert(Unit::Cm, Number::from(72) / Number::from(2.54));
62         from_pt.insert(Unit::Pc, Number::from(12));
63         from_pt.insert(Unit::Mm, Number::from(72) / Number::from(25.4));
64         from_pt.insert(Unit::Q, Number::from(72) / Number::from(101.6));
65         from_pt.insert(Unit::Pt, Number::one());
66         from_pt.insert(Unit::Px, Number::small_ratio(3, 4));
67 
68         let mut from_px = HashMap::new();
69         from_px.insert(Unit::In, Number::from(96));
70         from_px.insert(Unit::Cm, Number::from(96) / Number::from(2.54));
71         from_px.insert(Unit::Pc, Number::from(16));
72         from_px.insert(Unit::Mm, Number::from(96) / Number::from(25.4));
73         from_px.insert(Unit::Q, Number::from(96) / Number::from(101.6));
74         from_px.insert(Unit::Pt, Number::small_ratio(4, 3));
75         from_px.insert(Unit::Px, Number::one());
76 
77         let mut from_deg = HashMap::new();
78         from_deg.insert(Unit::Deg, Number::one());
79         from_deg.insert(Unit::Grad, Number::small_ratio(9, 10));
80         from_deg.insert(Unit::Rad, Number::from(180) / Number::from(PI));
81         from_deg.insert(Unit::Turn, Number::from(360));
82 
83         let mut from_grad = HashMap::new();
84         from_grad.insert(Unit::Deg, Number::small_ratio(10, 9));
85         from_grad.insert(Unit::Grad, Number::one());
86         from_grad.insert(Unit::Rad, Number::from(200) / Number::from(PI));
87         from_grad.insert(Unit::Turn, Number::from(400));
88 
89         let mut from_rad = HashMap::new();
90         from_rad.insert(Unit::Deg, Number::from(PI) / Number::from(180));
91         from_rad.insert(Unit::Grad, Number::from(PI) / Number::from(200));
92         from_rad.insert(Unit::Rad, Number::one());
93         from_rad.insert(Unit::Turn, Number::from(2.0 * PI));
94 
95         let mut from_turn = HashMap::new();
96         from_turn.insert(Unit::Deg, Number::small_ratio(1, 360));
97         from_turn.insert(Unit::Grad, Number::small_ratio(1, 400));
98         from_turn.insert(Unit::Rad, Number::one() / Number::from(2.0 * PI));
99         from_turn.insert(Unit::Turn, Number::one());
100 
101         let mut from_s = HashMap::new();
102         from_s.insert(Unit::S, Number::one());
103         from_s.insert(Unit::Ms, Number::small_ratio(1, 1000));
104 
105         let mut from_ms = HashMap::new();
106         from_ms.insert(Unit::S, Number::from(1000));
107         from_ms.insert(Unit::Ms, Number::one());
108 
109         let mut from_hz = HashMap::new();
110         from_hz.insert(Unit::Hz, Number::one());
111         from_hz.insert(Unit::Khz, Number::from(1000));
112 
113         let mut from_khz = HashMap::new();
114         from_khz.insert(Unit::Hz, Number::small_ratio(1, 1000));
115         from_khz.insert(Unit::Khz, Number::one());
116 
117         let mut from_dpi = HashMap::new();
118         from_dpi.insert(Unit::Dpi, Number::one());
119         from_dpi.insert(Unit::Dpcm, Number::from(2.54));
120         from_dpi.insert(Unit::Dppx, Number::from(96));
121 
122         let mut from_dpcm = HashMap::new();
123         from_dpcm.insert(Unit::Dpi, Number::one() / Number::from(2.54));
124         from_dpcm.insert(Unit::Dpcm, Number::one());
125         from_dpcm.insert(Unit::Dppx, Number::from(96) / Number::from(2.54));
126 
127         let mut from_dppx = HashMap::new();
128         from_dppx.insert(Unit::Dpi, Number::small_ratio(1, 96));
129         from_dppx.insert(Unit::Dpcm, Number::from(2.54) / Number::from(96));
130         from_dppx.insert(Unit::Dppx, Number::one());
131 
132         let mut m = HashMap::new();
133         m.insert(Unit::In, from_in);
134         m.insert(Unit::Cm, from_cm);
135         m.insert(Unit::Pc, from_pc);
136         m.insert(Unit::Mm, from_mm);
137         m.insert(Unit::Q, from_q);
138         m.insert(Unit::Pt, from_pt);
139         m.insert(Unit::Px, from_px);
140 
141         m.insert(Unit::Deg, from_deg);
142         m.insert(Unit::Grad, from_grad);
143         m.insert(Unit::Rad, from_rad);
144         m.insert(Unit::Turn, from_turn);
145 
146         m.insert(Unit::S, from_s);
147         m.insert(Unit::Ms, from_ms);
148 
149         m.insert(Unit::Hz, from_hz);
150         m.insert(Unit::Khz, from_khz);
151 
152         m.insert(Unit::Dpi, from_dpi);
153         m.insert(Unit::Dpcm, from_dpcm);
154         m.insert(Unit::Dppx, from_dppx);
155 
156         m
157     });
158