1pub struct QRMode;
5
6impl QRMode {
7 pub const MODE_NUMBER: i32 = 1;
8 pub const MODE_ALPHA_NUM: i32 = 2;
9 pub const MODE_8BIT_BYTE: i32 = 4;
10 pub const MODE_KANJI: i32 = 8;
11}
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
15pub enum QRErrorCorrectLevel {
16 L = 1, M = 0, Q = 3, #[default]
20 H = 2, }
22
23pub const PATTERN_POSITION_TABLE: &[[i32; 7]] = &[
25 [0, 0, 0, 0, 0, 0, 0],
26 [6, 18, 0, 0, 0, 0, 0],
27 [6, 22, 0, 0, 0, 0, 0],
28 [6, 26, 0, 0, 0, 0, 0],
29 [6, 30, 0, 0, 0, 0, 0],
30 [6, 34, 0, 0, 0, 0, 0],
31 [6, 22, 38, 0, 0, 0, 0],
32 [6, 24, 42, 0, 0, 0, 0],
33 [6, 26, 46, 0, 0, 0, 0],
34 [6, 28, 50, 0, 0, 0, 0],
35 [6, 30, 54, 0, 0, 0, 0],
36 [6, 32, 58, 0, 0, 0, 0],
37 [6, 34, 62, 0, 0, 0, 0],
38 [6, 26, 46, 66, 0, 0, 0],
39 [6, 26, 48, 70, 0, 0, 0],
40 [6, 26, 50, 74, 0, 0, 0],
41 [6, 30, 54, 78, 0, 0, 0],
42 [6, 30, 56, 82, 0, 0, 0],
43 [6, 30, 58, 86, 0, 0, 0],
44 [6, 34, 62, 90, 0, 0, 0],
45 [6, 28, 50, 72, 94, 0, 0],
46 [6, 26, 50, 74, 98, 0, 0],
47 [6, 30, 54, 78, 102, 0, 0],
48 [6, 28, 54, 80, 106, 0, 0],
49 [6, 32, 58, 84, 110, 0, 0],
50 [6, 30, 58, 86, 114, 0, 0],
51 [6, 34, 62, 90, 118, 0, 0],
52 [6, 26, 50, 74, 98, 122, 0],
53 [6, 30, 54, 78, 102, 126, 0],
54 [6, 26, 52, 78, 104, 130, 0],
55 [6, 30, 56, 82, 108, 134, 0],
56 [6, 34, 60, 86, 112, 138, 0],
57 [6, 30, 58, 86, 114, 142, 0],
58 [6, 34, 62, 90, 118, 146, 0],
59 [6, 30, 54, 78, 102, 126, 150],
60 [6, 24, 50, 76, 102, 128, 154],
61 [6, 28, 54, 80, 106, 132, 158],
62 [6, 32, 58, 84, 110, 136, 162],
63 [6, 26, 54, 82, 110, 138, 166],
64 [6, 30, 58, 86, 114, 142, 170],
65];
66
67pub const QR_CODE_LIMIT_LENGTH: &[[i32; 4]] = &[
69 [17, 14, 11, 7],
70 [32, 26, 20, 14],
71 [53, 42, 32, 24],
72 [78, 62, 46, 34],
73 [106, 84, 60, 44],
74 [134, 106, 74, 58],
75 [154, 122, 86, 64],
76 [192, 152, 108, 84],
77 [230, 180, 130, 98],
78 [271, 213, 151, 119],
79 [321, 251, 177, 137],
80 [367, 287, 203, 155],
81 [425, 331, 241, 177],
82 [458, 362, 258, 194],
83 [520, 412, 292, 220],
84 [586, 450, 322, 250],
85 [644, 504, 364, 280],
86 [718, 560, 394, 310],
87 [792, 624, 442, 338],
88 [858, 666, 482, 382],
89 [929, 711, 509, 403],
90 [1003, 779, 565, 439],
91 [1091, 857, 611, 461],
92 [1171, 911, 661, 511],
93 [1273, 997, 715, 535],
94 [1367, 1059, 751, 593],
95 [1465, 1125, 805, 625],
96 [1528, 1190, 868, 658],
97 [1628, 1264, 908, 698],
98 [1732, 1370, 982, 742],
99 [1840, 1452, 1030, 790],
100 [1952, 1538, 1112, 842],
101 [2068, 1628, 1168, 898],
102 [2188, 1722, 1228, 958],
103 [2303, 1809, 1283, 983],
104 [2431, 1911, 1351, 1051],
105 [2563, 1989, 1423, 1093],
106 [2699, 2099, 1499, 1139],
107 [2809, 2213, 1579, 1219],
108 [2953, 2331, 1663, 1273],
109];
110
111pub fn get_type_number(text: &str, correct_level: QRErrorCorrectLevel) -> i32 {
113 let length = text.len();
114 let level_map = [1, 0, 3, 2];
115 let level_index = level_map[correct_level as usize];
116 let data_length = length + 2; for (i, limits) in QR_CODE_LIMIT_LENGTH.iter().enumerate() {
119 let limit = limits[level_index as usize];
120 if data_length <= limit as usize {
121 return (i + 1) as i32;
122 }
123 }
124 40 }
126
127pub fn get_min_version(text_len: usize, level: QRErrorCorrectLevel) -> i32 {
129 let level_idx = match level {
130 QRErrorCorrectLevel::L => 0,
131 QRErrorCorrectLevel::M => 1,
132 QRErrorCorrectLevel::Q => 2,
133 QRErrorCorrectLevel::H => 3,
134 };
135
136 for (version, limits) in QR_CODE_LIMIT_LENGTH.iter().enumerate().skip(1).take(10) {
137 if limits[level_idx] >= text_len as i32 {
138 return version as i32;
139 }
140 }
141 10 }
143
144pub fn get_pattern_position(type_number: i32) -> Vec<i32> {
146 let pos = &PATTERN_POSITION_TABLE[(type_number - 1) as usize];
147 pos.iter().copied().filter(|&x| x > 0).collect()
148}
149
150#[cfg(test)]
151mod tests {
152 use super::*;
153
154 #[test]
155 fn test_error_correct_level_values() {
156 assert_eq!(QRErrorCorrectLevel::L as i32, 1);
157 assert_eq!(QRErrorCorrectLevel::M as i32, 0);
158 assert_eq!(QRErrorCorrectLevel::Q as i32, 3);
159 assert_eq!(QRErrorCorrectLevel::H as i32, 2);
160 }
161
162 #[test]
163 fn test_get_type_number_basic() {
164 let version = get_type_number("Hello", QRErrorCorrectLevel::H);
166 assert!((1..=40).contains(&version));
167 }
168
169 #[test]
170 fn test_get_min_version_fast() {
171 let v = get_min_version(5, QRErrorCorrectLevel::H);
173 assert!((1..=10).contains(&v));
174 }
175
176 #[test]
177 fn test_get_pattern_position() {
178 let pos = get_pattern_position(2);
179 assert_eq!(pos, vec![6, 18]);
180
181 let pos = get_pattern_position(7);
182 assert_eq!(pos, vec![6, 22, 38]);
183 }
184}