1fn prompt(msg: &str) -> String {
5 println!("{}\n", msg);
6 let mut input = String::new();
7 print!(">> ");
8
9 use std::io::{self, Write};
10 io::stdout().flush().unwrap();
11
12 io::stdin()
13 .read_line(&mut input)
14 .expect("Failed to read line");
15
16 input.trim().to_string()
17}
18
19fn parse_to_int(input: &str, default: i32) -> i32 {
21 match input.parse::<i32>() {
22 Ok(n) => n,
23 Err(_) => default,
24 }
25}
26
27fn parse_to_float(input: &str, default: f32) -> f32 {
29 match input.parse::<f32>() {
30 Ok(n) => n,
31 Err(_) => default,
32 }
33}
34
35fn choose_from_menu(choices: Vec<String>, msg: &str) -> String {
37 println!("Please choose an option:\n");
38
39 let choice_len = choices.len().try_into().expect("Too many choices.");
40
41 for (i, choice) in choices.iter().enumerate() {
42 println!("{}. {}", i + 1, choice);
43 }
44
45 println!();
46
47 let selection = loop {
48 let choice = prompt(msg);
49 let choice = parse_to_int(&choice, 0);
50
51 if choice > 0 && choice <= choice_len {
52 break (choice - 1) as usize;
53 } else {
54 println!("Invalid choice.");
55 }
56 };
57
58 choices.get(selection).unwrap().to_string()
59}
60
61use cock_lib::{
62 cock_parts::{Abnormalities, Curvature, Size, SizeType},
63 FromString, GetVariants, InnerUser, ID
64};
65
66fn input<T: GetVariants + FromString>(message: &str) -> T {
68 let choice = choose_from_menu(T::get_variants(), message);
69 let variant = T::from_string(&choice);
70 clear_screen();
71 variant
72}
73
74fn get_user() -> ID {
76 let user_type = choose_from_menu(ID::get_variants(), "ID type:");
77 let user = match user_type.as_str() {
78 "Anonymous" => ID::Anonymous,
79 "User" => {
80 clear_screen();
81 let name = prompt("User Name:");
82 clear_screen();
83 let discord_name = prompt("Discord Name:");
84 ID::User(InnerUser { name, discord_name })
85 }
86 _ => panic!("Invalid user type"),
87 };
88 clear_screen();
89 user
90}
91
92fn get_size() -> Size {
94 let size_type = choose_from_menu(SizeType::get_variants(), "Inches or Centimeters?");
95 let length = parse_to_float(prompt("Cock length:").as_str(), 0.0);
96 let girth = parse_to_float(prompt("Cock girth:").as_str(), 0.0);
97
98 let size = match size_type.as_str() {
99 "Inches" => Size::from_in(length, girth),
100 "Centimeters" => Size::from_cm(length, girth),
101 _ => panic!("Invalid size type"),
102 };
103 clear_screen();
104 size
105}
106
107fn clear_screen() {
109 print!("{esc}[2J{esc}[1;1H", esc = 27 as char);
110}
111
112use cock_lib::{CockHandler, CockStruct, cock_parts::Shape};
113
114pub fn cock_handler_build() -> CockHandler {
116 let id = get_user();
117 let size = get_size();
118 let aesthetic = input("Choose aesthetic:");
119 let balls = input("Choose ball size:");
120 let shape = {
121 let in_shape = input("Choose cock shape:");
122 match in_shape {
123 Shape::Other(_) => {
124 let val = prompt("Define the shape:");
125 clear_screen();
126 Shape::Other(val)
127 }
128 _ => in_shape,
129 }
130 };
131 let curvature = {
132 let in_curv = input("Choose cock curvature:");
133 match in_curv {
134 Curvature::Other(_) => {
135 let val = prompt("Define the curvature:");
136 clear_screen();
137 Curvature::Other(val)
138 }
139 _ => in_curv,
140 }
141 };
142 let circumcision = input("Choose cirumcision status:");
143 let veininess = input("Choose veininess level:");
144 let abnormalities = {
145 let in_abnor = input("Choose cock abnormalities:");
146 match in_abnor {
147 Abnormalities::Major(_) => {
148 let val = prompt("Define the major abnormalities:");
149 clear_screen();
150 Abnormalities::Major(val)
151 }
152 Abnormalities::Minor(_) => {
153 let val = prompt("Define the minor abnormalities:");
154 clear_screen();
155 Abnormalities::Minor(val)
156 }
157 _ => in_abnor,
158 }
159 };
160
161 let cock = CockStruct {
162 size,
163 aesthetic,
164 balls,
165 shape,
166 curvature,
167 circumcision,
168 veininess,
169 abnormalities,
170 };
171
172 CockHandler { id, cock }
173}