konduto/types/vehicle/
vehicle_type.rs1use crate::types::validation_errors::ValidationError;
2use serde::{Deserialize, Serialize};
3use std::fmt;
4
5#[derive(Debug, Clone, PartialEq, Eq, Hash)]
7pub enum VehicleType {
8 Car,
10 Bus,
12 Truck,
14 Motorcycle,
16 Aircraft,
18 Boat,
20 Bicycle,
22 Other(String),
24}
25
26impl VehicleType {
27 const MAX_LENGTH: usize = 15;
28
29 pub fn new(value: impl Into<String>) -> Result<Self, ValidationError> {
31 let input = value.into();
32 let trimmed = input.trim().to_lowercase();
33
34 if trimmed.is_empty() {
35 return Err(ValidationError::EmptyField("vehicle_type".to_string()));
36 }
37
38 if trimmed.len() > Self::MAX_LENGTH {
39 return Err(ValidationError::TooLong {
40 field: "vehicle_type".to_string(),
41 max: Self::MAX_LENGTH,
42 actual: trimmed.len(),
43 });
44 }
45
46 Ok(match trimmed.as_str() {
47 "car" => Self::Car,
48 "bus" => Self::Bus,
49 "truck" => Self::Truck,
50 "motorcycle" => Self::Motorcycle,
51 "aircraft" => Self::Aircraft,
52 "boat" => Self::Boat,
53 "bicycle" => Self::Bicycle,
54 other => Self::Other(other.to_string()),
55 })
56 }
57
58 pub fn as_str(&self) -> &str {
59 match self {
60 Self::Car => "car",
61 Self::Bus => "bus",
62 Self::Truck => "truck",
63 Self::Motorcycle => "motorcycle",
64 Self::Aircraft => "aircraft",
65 Self::Boat => "boat",
66 Self::Bicycle => "bicycle",
67 Self::Other(s) => s,
68 }
69 }
70}
71
72impl fmt::Display for VehicleType {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 write!(f, "{}", self.as_str())
75 }
76}
77
78impl Serialize for VehicleType {
79 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
80 where
81 S: serde::Serializer,
82 {
83 serializer.serialize_str(self.as_str())
84 }
85}
86
87impl<'de> Deserialize<'de> for VehicleType {
88 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
89 where
90 D: serde::Deserializer<'de>,
91 {
92 let s = String::deserialize(deserializer)?;
93 VehicleType::new(s).map_err(serde::de::Error::custom)
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100
101 #[test]
102 fn test_vehicle_type_from_str() {
103 assert_eq!(VehicleType::new("car").unwrap(), VehicleType::Car);
104 assert_eq!(VehicleType::new("Bus").unwrap(), VehicleType::Bus);
105 assert_eq!(VehicleType::new("TRUCK").unwrap(), VehicleType::Truck);
106 }
107
108 #[test]
109 fn test_vehicle_type_other() {
110 let custom = VehicleType::new("scooter").unwrap();
111 assert_eq!(custom.as_str(), "scooter");
112 }
113
114 #[test]
115 fn test_vehicle_type_serialization() {
116 let car = VehicleType::Car;
117 let json = serde_json::to_string(&car).unwrap();
118 assert_eq!(json, r#""car""#);
119 }
120}
121