1use std::fmt;
4
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
20#[serde(transparent)]
21pub struct Tech(String);
22
23impl Tech {
24 pub fn new(value: &str) -> Self {
26 Self(value.to_owned())
27 }
28
29 pub fn as_str(&self) -> &str {
31 &self.0
32 }
33}
34
35impl fmt::Display for Tech {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 f.write_str(&self.0)
38 }
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44
45 #[test]
46 fn test_display() {
47 let tech = Tech::new("TypeScript");
48 assert_eq!(format!("{tech}"), "TypeScript");
49 }
50
51 #[test]
52 fn test_serde_round_trip() {
53 let tech = Tech::new("axum");
54 let json = serde_json::to_string(&tech).unwrap();
55 assert_eq!(json, "\"axum\"");
56 let deserialized: Tech = serde_json::from_str(&json).unwrap();
57 assert_eq!(tech, deserialized);
58 }
59
60 #[test]
61 fn test_as_str() {
62 let tech = Tech::new("React");
63 assert_eq!(tech.as_str(), "React");
64 }
65
66 #[test]
67 fn test_debug() {
68 let tech = Tech::new("Rust");
69 let debug = format!("{tech:?}");
70 assert!(debug.contains("Rust"));
71 }
72
73 #[test]
74 fn test_clone_eq() {
75 let a = Tech::new("Go");
76 let b = a.clone();
77 assert_eq!(a, b);
78 }
79
80 #[test]
81 fn test_hash() {
82 use std::collections::HashSet;
83 let mut set = HashSet::new();
84 set.insert(Tech::new("Rust"));
85 set.insert(Tech::new("Go"));
86 set.insert(Tech::new("Rust"));
87 assert_eq!(set.len(), 2);
88 }
89}