1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub enum BarcodeType {
30 Code39,
32}
33
34impl BarcodeType {
35 pub fn from_xfa_name(naam: &str) -> Option<Self> {
43 match naam.trim().to_ascii_lowercase().as_str() {
44 "code39" | "code3of9" => Some(Self::Code39),
45 _ => None,
46 }
47 }
48}
49
50const CODE39: &[(char, [bool; 9])] = &[
56 (
57 '0',
58 [false, false, false, true, true, false, true, false, false],
59 ),
60 (
61 '1',
62 [true, false, false, true, false, false, false, false, true],
63 ),
64 (
65 '2',
66 [false, false, true, true, false, false, false, false, true],
67 ),
68 (
69 '3',
70 [true, false, true, true, false, false, false, false, false],
71 ),
72 (
73 '4',
74 [false, false, false, true, true, false, false, false, true],
75 ),
76 (
77 '5',
78 [true, false, false, true, true, false, false, false, false],
79 ),
80 (
81 '6',
82 [false, false, true, true, true, false, false, false, false],
83 ),
84 (
85 '7',
86 [false, false, false, true, false, false, true, false, true],
87 ),
88 (
89 '8',
90 [true, false, false, true, false, false, true, false, false],
91 ),
92 (
93 '9',
94 [false, false, true, true, false, false, true, false, false],
95 ),
96 (
97 'A',
98 [true, false, false, false, false, true, false, false, true],
99 ),
100 (
101 'B',
102 [false, false, true, false, false, true, false, false, true],
103 ),
104 (
105 'C',
106 [true, false, true, false, false, true, false, false, false],
107 ),
108 (
109 'D',
110 [false, false, false, false, true, true, false, false, true],
111 ),
112 (
113 'E',
114 [true, false, false, false, true, true, false, false, false],
115 ),
116 (
117 'F',
118 [false, false, true, false, true, true, false, false, false],
119 ),
120 (
121 'G',
122 [false, false, false, false, false, true, true, false, true],
123 ),
124 (
125 'H',
126 [true, false, false, false, false, true, true, false, false],
127 ),
128 (
129 'I',
130 [false, false, true, false, false, true, true, false, false],
131 ),
132 (
133 'J',
134 [false, false, false, false, true, true, true, false, false],
135 ),
136 (
137 'K',
138 [true, false, false, false, false, false, false, true, true],
139 ),
140 (
141 'L',
142 [false, false, true, false, false, false, false, true, true],
143 ),
144 (
145 'M',
146 [true, false, true, false, false, false, false, true, false],
147 ),
148 (
149 'N',
150 [false, false, false, false, true, false, false, true, true],
151 ),
152 (
153 'O',
154 [true, false, false, false, true, false, false, true, false],
155 ),
156 (
157 'P',
158 [false, false, true, false, true, false, false, true, false],
159 ),
160 (
161 'Q',
162 [false, false, false, false, false, false, true, true, true],
163 ),
164 (
165 'R',
166 [true, false, false, false, false, false, true, true, false],
167 ),
168 (
169 'S',
170 [false, false, true, false, false, false, true, true, false],
171 ),
172 (
173 'T',
174 [false, false, false, false, true, false, true, true, false],
175 ),
176 (
177 'U',
178 [true, true, false, false, false, false, false, false, true],
179 ),
180 (
181 'V',
182 [false, true, true, false, false, false, false, false, true],
183 ),
184 (
185 'W',
186 [true, true, true, false, false, false, false, false, false],
187 ),
188 (
189 'X',
190 [false, true, false, false, true, false, false, false, true],
191 ),
192 (
193 'Y',
194 [true, true, false, false, true, false, false, false, false],
195 ),
196 (
197 'Z',
198 [false, true, true, false, true, false, false, false, false],
199 ),
200 (
201 '-',
202 [false, true, false, false, false, false, true, false, true],
203 ),
204 (
205 '.',
206 [true, true, false, false, false, false, true, false, false],
207 ),
208 (
209 ' ',
210 [false, true, true, false, false, false, true, false, false],
211 ),
212 (
213 '$',
214 [false, true, false, true, false, true, false, false, false],
215 ),
216 (
217 '/',
218 [false, true, false, true, false, false, false, true, false],
219 ),
220 (
221 '+',
222 [false, true, false, false, false, true, false, true, false],
223 ),
224 (
225 '%',
226 [false, false, false, true, false, true, false, true, false],
227 ),
228 (
229 '*',
230 [false, true, false, false, true, false, true, false, false],
231 ),
232];
233
234fn patroon(c: char) -> Option<[bool; 9]> {
235 let boven = c.to_ascii_uppercase();
236 CODE39.iter().find(|(k, _)| *k == boven).map(|(_, p)| *p)
237}
238
239#[derive(Debug, Clone, Copy, PartialEq)]
241pub struct Element {
242 pub is_bar: bool,
244 pub modules: u8,
246}
247
248pub fn encode_code39(tekst: &str) -> Option<Vec<Element>> {
254 let met_bookends: String = format!("*{}*", tekst.to_ascii_uppercase());
256 let mut uit = Vec::new();
257 for (i, c) in met_bookends.chars().enumerate() {
258 if c == '*' && i != 0 && i != met_bookends.chars().count() - 1 {
259 return None;
261 }
262 let p = patroon(c)?;
263 for (j, breed) in p.iter().enumerate() {
264 uit.push(Element {
265 is_bar: j % 2 == 0,
266 modules: if *breed { 3 } else { 1 },
267 });
268 }
269 uit.push(Element {
271 is_bar: false,
272 modules: 1,
273 });
274 }
275 uit.pop(); Some(uit)
277}
278
279pub fn total_modules(elementen: &[Element]) -> u32 {
281 elementen.iter().map(|e| u32::from(e.modules)).sum()
282}