initiative_core/world/npc/
size.rs1use serde::{Deserialize, Serialize};
2use std::fmt;
3
4#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
5#[serde(tag = "type")]
6pub enum Size {
7 Tiny { height: u16, weight: u16 },
8 Small { height: u16, weight: u16 },
9 Medium { height: u16, weight: u16 },
10 }
14
15impl Size {
16 pub fn height_weight(&self) -> (u16, u16) {
17 match self {
18 Self::Tiny { height, weight } => (*height, *weight),
19 Self::Small { height, weight } => (*height, *weight),
20 Self::Medium { height, weight } => (*height, *weight),
21 }
22 }
23
24 pub fn height(&self) -> u16 {
25 self.height_weight().0
26 }
27
28 pub fn height_ft_in(&self) -> (u8, u8) {
29 let height = self.height();
30 ((height / 12) as u8, (height % 12) as u8)
31 }
32
33 pub fn weight(&self) -> u16 {
34 self.height_weight().1
35 }
36
37 pub fn name(&self) -> &'static str {
38 match self {
39 Self::Tiny { .. } => "tiny",
40 Self::Small { .. } => "small",
41 Self::Medium { .. } => "medium",
42 }
43 }
44}
45
46impl fmt::Display for Size {
47 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
48 let (height_ft, height_in) = self.height_ft_in();
49 write!(
50 f,
51 "{}'{}\", {} lbs ({})",
52 height_ft,
53 height_in,
54 self.weight(),
55 self.name(),
56 )
57 }
58}
59
60#[cfg(test)]
61mod test {
62 use super::*;
63
64 #[test]
65 fn height_weight_test() {
66 assert_eq!(
67 (71, 140),
68 Size::Small {
69 height: 71,
70 weight: 140
71 }
72 .height_weight()
73 );
74
75 assert_eq!(
76 (71, 140),
77 Size::Medium {
78 height: 71,
79 weight: 140
80 }
81 .height_weight()
82 );
83 }
84
85 #[test]
86 fn height_test() {
87 assert_eq!(71, size().height());
88 }
89
90 #[test]
91 fn height_ft_in_test() {
92 assert_eq!((5, 11), size().height_ft_in());
93 }
94
95 #[test]
96 fn weight_test() {
97 assert_eq!(140, size().weight());
98 }
99
100 #[test]
101 fn name_test() {
102 assert_eq!(
103 "small",
104 Size::Small {
105 height: 0,
106 weight: 0
107 }
108 .name()
109 );
110 assert_eq!(
111 "medium",
112 Size::Medium {
113 height: 0,
114 weight: 0
115 }
116 .name()
117 );
118 }
119
120 #[test]
121 fn fmt_test() {
122 assert_eq!("5'11\", 140 lbs (medium)", format!("{}", size()));
123 }
124
125 #[test]
126 fn serialize_deserialize_test() {
127 assert_eq!(
128 r#"{"type":"Medium","height":71,"weight":140}"#,
129 serde_json::to_string(&size()).unwrap(),
130 );
131
132 let value: Size =
133 serde_json::from_str(r#"{"type":"Medium","height":71,"weight":140}"#).unwrap();
134 assert_eq!(size(), value);
135 }
136
137 fn size() -> Size {
138 Size::Medium {
139 height: 71,
140 weight: 140,
141 }
142 }
143}