cock_lib/cock_parts/
size.rs

1use crate::{FromString, GetVariants, Score};
2
3/// [SizeType] is an enum that represents the metric of measurement for the cocks [Size]
4#[derive(Debug, PartialEq, Clone, Copy, serde::Deserialize)]
5pub enum SizeType {
6    Centimeters,
7    Inches,
8}
9
10/// The [Score] trait implementation for [SizeType] provides a score value based on the size type.
11impl GetVariants for SizeType {
12    fn get_variants() -> Vec<String> {
13        vec![String::from("Centimeters"), String::from("Inches")]
14    }
15}
16
17/// The [FromString] trait implementation for [SizeType] returns a [SizeType] variant based on the string provided.
18impl FromString for SizeType {
19    fn from_string(size_type: &str) -> SizeType {
20        match size_type {
21            "Centimeters" => SizeType::Centimeters,
22            "Inches" => SizeType::Inches,
23            _ => panic!("Invalid size type"),
24        }
25    }
26}
27
28/// [Size] is a struct that represents the size of a cock.
29#[derive(Debug, Clone, serde::Deserialize)]
30pub struct Size {
31    pub length: f32,
32    pub girth: f32,
33    pub size_type: SizeType,
34}
35
36/// Implementation of [Score] trait for [Size]. The score is calculated based on the size type.
37impl Size {
38    /// Function to create a Size instance from given length and girth in centimeters.
39    pub fn from_cm(length: f32, girth: f32) -> Size {
40        Size {
41            length,
42            girth,
43            size_type: SizeType::Centimeters,
44        }
45    }
46
47    /// Function to create a [Size] instance from given length and girth in inches.
48    pub fn from_in(length: f32, girth: f32) -> Size {
49        Size {
50            length,
51            girth,
52            size_type: SizeType::Inches,
53        }
54    }
55}
56
57impl Score for Size {
58    /// Function to calculate the score of a [Size] instance.
59    fn score(&self) -> u32 {
60        match self {
61            Size {
62                size_type: SizeType::Inches,
63                ..
64            } => {
65                let length_score = match (self.length * 10.0) as u32 {
66                    0..=35 => 1,
67                    36..=50 => 2,
68                    51..=57 => 3,
69                    58..=70 => 4,
70                    71..=80 => 5,
71                    _ => 2,
72                };
73
74                let girth_score = match (self.girth * 10.0) as u32 {
75                    0..=33 => 1,
76                    34..=40 => 2,
77                    41..=46 => 3,
78                    47..=54 => 4,
79                    55..=63 => 5,
80                    _ => 2,
81                };
82                length_score + girth_score
83            }
84            Size {
85                size_type: SizeType::Centimeters,
86                ..
87            } => {
88                let length_score = match (self.length * 10.0) as u32 {
89                    0..=90 => 1,
90                    91..=125 => 2,
91                    126..=145 => 3,
92                    146..=175 => 4,
93                    176..=200 => 5,
94                    _ => 1,
95                };
96
97                let girth_score = match (self.girth * 10.0) as u32 {
98                    0..=85 => 1,
99                    86..=100 => 2,
100                    101..=115 => 3,
101                    116..=135 => 4,
102                    136..=155 => 5,
103                    _ => 1,
104                };
105
106                length_score + girth_score
107            }
108        }
109    }
110}
111
112/// Implementation of [std::fmt::Display] trait for [Size].
113impl std::fmt::Display for Size {
114    /// Function to format the [Size] instance.
115    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
116        match self.size_type {
117            SizeType::Centimeters => write!(f, "{}cm x {}cm", self.length, self.girth),
118            SizeType::Inches => write!(f, "{}in x {}in", self.length, self.girth),
119        }
120    }
121}