1use std::fmt;
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
10#[serde(transparent)]
11pub struct Cik(u64);
12
13impl Cik {
14 pub fn new(value: u64) -> Self {
16 Self(value)
17 }
18
19 pub fn as_u64(self) -> u64 {
21 self.0
22 }
23
24 pub fn to_padded_string(self) -> String {
26 format!("{:010}", self.0)
27 }
28}
29
30impl fmt::Display for Cik {
31 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32 write!(f, "{}", self.0)
33 }
34}
35
36impl From<u64> for Cik {
37 fn from(value: u64) -> Self {
38 Self(value)
39 }
40}
41
42impl From<u32> for Cik {
43 fn from(value: u32) -> Self {
44 Self(value as u64)
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 #[test]
53 fn new_and_as_u64() {
54 let cik = Cik::new(320193);
55 assert_eq!(cik.as_u64(), 320193);
56 }
57
58 #[test]
59 fn to_padded_string_normal() {
60 assert_eq!(Cik::new(320193).to_padded_string(), "0000320193");
61 }
62
63 #[test]
64 fn to_padded_string_small() {
65 assert_eq!(Cik::new(1).to_padded_string(), "0000000001");
66 }
67
68 #[test]
69 fn to_padded_string_large() {
70 assert_eq!(Cik::new(1234567890).to_padded_string(), "1234567890");
71 }
72
73 #[test]
74 fn to_padded_string_zero() {
75 assert_eq!(Cik::new(0).to_padded_string(), "0000000000");
76 }
77
78 #[test]
79 fn display_shows_raw_number() {
80 assert_eq!(format!("{}", Cik::new(320193)), "320193");
81 assert_eq!(format!("{}", Cik::new(0)), "0");
82 }
83
84 #[test]
85 fn from_u64() {
86 let cik: Cik = 320193_u64.into();
87 assert_eq!(cik.as_u64(), 320193);
88 }
89
90 #[test]
91 fn from_u32() {
92 let cik: Cik = 320193_u32.into();
93 assert_eq!(cik.as_u64(), 320193);
94 }
95
96 #[test]
97 fn equality() {
98 assert_eq!(Cik::new(100), Cik::new(100));
99 assert_ne!(Cik::new(100), Cik::new(200));
100 }
101
102 #[test]
103 fn hash_consistent() {
104 use std::collections::HashSet;
105 let mut set = HashSet::new();
106 set.insert(Cik::new(320193));
107 assert!(set.contains(&Cik::new(320193)));
108 assert!(!set.contains(&Cik::new(1)));
109 }
110
111 #[test]
112 fn clone_and_copy() {
113 let a = Cik::new(42);
114 let b = a; let c = a; assert_eq!(a, b);
117 assert_eq!(a, c);
118 }
119
120 #[test]
121 fn serde_roundtrip() {
122 let cik = Cik::new(320193);
123 let json = serde_json::to_string(&cik).unwrap();
124 assert_eq!(json, "320193");
125 let deserialized: Cik = serde_json::from_str(&json).unwrap();
126 assert_eq!(deserialized, cik);
127 }
128
129 #[test]
130 fn serde_transparent_in_struct() {
131 #[derive(serde::Serialize, serde::Deserialize, PartialEq, Debug)]
132 struct Wrapper {
133 cik: Cik,
134 }
135 let w = Wrapper {
136 cik: Cik::new(320193),
137 };
138 let json = serde_json::to_string(&w).unwrap();
139 assert_eq!(json, r#"{"cik":320193}"#);
140 let back: Wrapper = serde_json::from_str(&json).unwrap();
141 assert_eq!(back, w);
142 }
143}