barcoders/generators/
json.rs

1//! Functionality for generating JSON representations of barcodes.
2//!
3//! This is useful for passing encoded data to third-party systems in a conventional format.
4//!
5//! Output will be of the format:
6//! ```javascript
7//! {
8//!   "height": 10,
9//!   "xdim": 1,
10//!   "encoding": [1, 0, 0, 1, 1, 0, ...],
11//! }
12//! ```
13
14use crate::error::Result;
15#[cfg(not(feature = "std"))]
16use alloc::{format, string::String};
17
18/// The JSON  barcode generator type.
19#[derive(Copy, Clone, Debug)]
20pub struct JSON {
21    /// The height of the barcode.
22    pub height: usize,
23    /// The X dimension. Specifies the width of the "narrow" bars.
24    pub xdim: usize,
25}
26
27impl Default for JSON {
28    fn default() -> Self {
29        Self::new()
30    }
31}
32
33impl JSON {
34    /// Returns a new JSON with default values.
35    pub fn new() -> JSON {
36        JSON {
37            height: 10,
38            xdim: 1,
39        }
40    }
41
42    /// Generates the given barcode. Returns a `Result<String, Error>` indicating success.
43    pub fn generate<T: AsRef<[u8]>>(&self, barcode: T) -> Result<String> {
44        let mut bits = barcode.as_ref().iter().fold(String::new(), |acc, &b| {
45            let n = match b {
46                0 => "0",
47                _ => "1",
48            };
49
50            acc + n + ","
51        });
52
53        // Kill trailing comma.
54        bits.pop();
55
56        let output = format!(
57            "{{\"height\":{},\"xdim\":{},\"encoding\":[{}]}}",
58            self.height, self.xdim, bits
59        );
60
61        Ok(output)
62    }
63}
64
65#[cfg(test)]
66mod tests {
67    use crate::generators::json::*;
68    use crate::sym::codabar::*;
69    use crate::sym::code11::*;
70    use crate::sym::code128::*;
71    use crate::sym::code39::*;
72    use crate::sym::code93::*;
73    use crate::sym::ean13::*;
74    use crate::sym::ean8::*;
75    use crate::sym::ean_supp::*;
76    use crate::sym::tf::*;
77
78    #[test]
79    fn ean_13_as_json() {
80        let ean13 = EAN13::new("750103131130").unwrap();
81        let json = JSON::new();
82        let generated = json.generate(&ean13.encode()[..]).unwrap();
83
84        assert_eq!(generated, "{\"height\":10,\"xdim\":1,\"encoding\":[1,0,1,0,1,1,0,0,0,1,0,1,0,0,1,1,1,0,0,1,1,0,0,1,0,1,0,0,1,1,1,0,1,1,1,1,0,1,0,1,1,0,0,1,1,0,1,0,1,0,1,0,0,0,0,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,0,0,0,0,1,0,1,1,1,0,0,1,0,1,1,1,0,1,0,0,1,0,1]}".trim());
85    }
86
87    #[test]
88    fn ean_13_as_json_small_height_double_width() {
89        let ean13 = EAN13::new("750103131130").unwrap();
90        let json = JSON { height: 6, xdim: 2 };
91        let generated = json.generate(&ean13.encode()[..]).unwrap();
92
93        assert_eq!(generated, "{\"height\":6,\"xdim\":2,\"encoding\":[1,0,1,0,1,1,0,0,0,1,0,1,0,0,1,1,1,0,0,1,1,0,0,1,0,1,0,0,1,1,1,0,1,1,1,1,0,1,0,1,1,0,0,1,1,0,1,0,1,0,1,0,0,0,0,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,0,0,0,0,1,0,1,1,1,0,0,1,0,1,1,1,0,1,0,0,1,0,1]}".trim());
94    }
95
96    #[test]
97    fn ean_8_as_json() {
98        let ean8 = EAN8::new("1234567").unwrap();
99        let json = JSON::new();
100        let generated = json.generate(&ean8.encode()[..]).unwrap();
101
102        assert_eq!(generated, "{\"height\":10,\"xdim\":1,\"encoding\":[1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,1,0,1,0,0,0,1,1,0,1,0,1,0,1,0,0,1,1,1,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,1,1,1,0,0,1,0,1,0,1]}".trim());
103    }
104
105    #[test]
106    fn ean_8_as_json_small_height_double_width() {
107        let ean8 = EAN8::new("1234567").unwrap();
108        let json = JSON { height: 5, xdim: 2 };
109        let generated = json.generate(&ean8.encode()[..]).unwrap();
110
111        assert_eq!(generated, "{\"height\":5,\"xdim\":2,\"encoding\":[1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,1,0,1,0,0,0,1,1,0,1,0,1,0,1,0,0,1,1,1,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,1,1,1,0,0,1,0,1,0,1]}".trim());
112    }
113
114    #[test]
115    fn code_93_as_json() {
116        let code93 = Code93::new("MONKEYMAGIC").unwrap();
117        let json = JSON::new();
118        let generated = json.generate(&code93.encode()[..]).unwrap();
119
120        assert_eq!(generated, "{\"height\":10,\"xdim\":1,\"encoding\":[1,0,1,0,1,1,1,1,0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,0,1,0,1,0,0,0,1,1,0,1,0,0,0,1,1,0,1,0,1,1,0,0,1,0,0,1,0,1,0,0,1,1,0,1,1,0,1,0,1,0,0,1,1,0,0,1,1,0,1,0,1,0,0,0,1,0,1,1,0,1,0,0,0,1,0,1,1,0,0,0,1,0,1,1,0,1,0,0,0,1,0,1,0,0,1,1,0,1,1,0,1,0,1,0,0,1,0,0,0,1,0,1,0,1,1,1,1,0,1]}".trim());
121    }
122
123    #[test]
124    fn code_93_as_json_small_height_double_weight() {
125        let code93 = Code93::new("1234").unwrap();
126        let json = JSON { height: 7, xdim: 2 };
127        let generated = json.generate(&code93.encode()[..]).unwrap();
128
129        assert_eq!(generated, "{\"height\":7,\"xdim\":2,\"encoding\":[1,0,1,0,1,1,1,1,0,1,0,1,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,1,0,1,0,0,0,0,1,0,1,0,0,1,0,1,0,0,0,1,0,0,0,1,1,0,1,0,1,0,1,0,0,0,0,1,0,1,0,1,0,1,1,1,1,0,1]}".trim());
130    }
131
132    #[test]
133    fn code_39_as_json() {
134        let code39 = Code39::new("TEST8052").unwrap();
135        let json = JSON::new();
136        let generated = json.generate(&code39.encode()[..]).unwrap();
137
138        assert_eq!(generated, "{\"height\":10,\"xdim\":1,\"encoding\":[1,0,0,1,0,1,1,0,1,1,0,1,0,1,0,1,0,1,1,0,1,1,0,0,1,0,1,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,1,0,1,0,1,0,0,1,1,0,1,1,0,1,0,1,1,0,1,0,0,1,1,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,1,0,1,0,0,1,0,1,1,0,1,1,0,1]}".trim());
139    }
140
141    #[test]
142    fn code_39_as_json_small_height_double_weight() {
143        let code39 = Code39::new("1234").unwrap();
144        let json = JSON { height: 7, xdim: 2 };
145        let generated = json.generate(&code39.encode()[..]).unwrap();
146
147        assert_eq!(generated, "{\"height\":7,\"xdim\":2,\"encoding\":[1,0,0,1,0,1,1,0,1,1,0,1,0,1,1,0,1,0,0,1,0,1,0,1,1,0,1,0,1,1,0,0,1,0,1,0,1,1,0,1,1,0,1,1,0,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,1,0,1,1,0,1,0,0,1,0,1,1,0,1,1,0,1]}".trim());
148    }
149
150    #[test]
151    fn codabar_as_json() {
152        let codabar = Codabar::new("A98B").unwrap();
153        let json = JSON::new();
154        let generated = json.generate(&codabar.encode()[..]).unwrap();
155
156        assert_eq!(generated, "{\"height\":10,\"xdim\":1,\"encoding\":[1,0,1,1,0,0,1,0,0,1,0,1,1,0,1,0,0,1,0,1,0,1,0,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0,1,1]}".trim());
157    }
158
159    #[test]
160    fn codabar_as_json_small_height_double_weight() {
161        let codabar = Codabar::new("A40156B").unwrap();
162        let json = JSON { height: 7, xdim: 2 };
163        let generated = json.generate(&codabar.encode()[..]).unwrap();
164
165        assert_eq!(generated, "{\"height\":7,\"xdim\":2,\"encoding\":[1,0,1,1,0,0,1,0,0,1,0,1,0,1,1,0,1,0,0,1,0,1,0,1,0,1,0,0,1,1,0,1,0,1,0,1,1,0,0,1,0,1,1,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,1,1,0,1,0,1,0,0,1,0,0,1,1]}".trim());
166    }
167
168    #[test]
169    fn code_128_as_json() {
170        let code128 = Code128::new("ÀHELLO").unwrap();
171        let json = JSON::new();
172        let generated = json.generate(&code128.encode()[..]).unwrap();
173
174        assert_eq!(generated, "{\"height\":10,\"xdim\":1,\"encoding\":[1,1,0,1,0,0,0,0,1,0,0,1,1,0,0,0,1,0,1,0,0,0,1,0,0,0,1,1,0,1,0,0,0,1,0,0,0,1,1,0,1,1,1,0,1,0,0,0,1,1,0,1,1,1,0,1,0,0,0,1,1,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,0,1,1,0,0,0,1,1,1,0,1,0,1,1]}".trim());
175    }
176
177    #[test]
178    fn code_128_as_json_small_height_double_weight() {
179        let code128 = Code128::new("ÀHELLO").unwrap();
180        let json = JSON { height: 7, xdim: 2 };
181        let generated = json.generate(&code128.encode()[..]).unwrap();
182
183        assert_eq!(generated, "{\"height\":7,\"xdim\":2,\"encoding\":[1,1,0,1,0,0,0,0,1,0,0,1,1,0,0,0,1,0,1,0,0,0,1,0,0,0,1,1,0,1,0,0,0,1,0,0,0,1,1,0,1,1,1,0,1,0,0,0,1,1,0,1,1,1,0,1,0,0,0,1,1,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,0,1,1,0,0,0,1,1,1,0,1,0,1,1]}".trim());
184    }
185
186    #[test]
187    fn ean2_as_json() {
188        let ean2 = EANSUPP::new("34").unwrap();
189        let json = JSON::new();
190        let generated = json.generate(&ean2.encode()[..]).unwrap();
191
192        assert_eq!(
193            generated,
194            "{\"height\":10,\"xdim\":1,\"encoding\":[1,0,1,1,0,1,0,0,0,0,1,0,1,0,1,0,0,0,1,1]}"
195                .trim()
196        );
197    }
198
199    #[test]
200    fn ean5_as_json() {
201        let ean5 = EANSUPP::new("50799").unwrap();
202        let json = JSON::new();
203        let generated = json.generate(&ean5.encode()[..]).unwrap();
204
205        assert_eq!(generated, "{\"height\":10,\"xdim\":1,\"encoding\":[1,0,1,1,0,1,1,0,0,0,1,0,1,0,1,0,0,1,1,1,0,1,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,1,0,1,0,0,0,1,0,1,1]}".trim());
206    }
207
208    #[test]
209    fn itf_as_json() {
210        let itf = TF::interleaved("12345").unwrap();
211        let json = JSON::new();
212        let generated = json.generate(&itf.encode()[..]).unwrap();
213
214        assert_eq!(generated, "{\"height\":10,\"xdim\":1,\"encoding\":[1,0,1,0,1,1,1,0,1,0,0,0,1,0,1,0,1,1,1,0,0,0,1,1,1,0,1,1,1,0,1,0,0,0,1,0,1,0,0,0,1,1,1,0,1,0,1,1,1,0,1,0,0,0,1,0,0,0,1,1,0,1]}".trim());
215    }
216
217    #[test]
218    fn code11_as_json() {
219        let code11 = Code11::new("111-999-8").unwrap();
220        let json = JSON::new();
221        let generated = json.generate(&code11.encode()[..]).unwrap();
222
223        assert_eq!(generated, "{\"height\":10,\"xdim\":1,\"encoding\":[1,0,1,1,0,0,1,0,1,1,0,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,0,1,0,1,1,0,1,0,1,1,0,1,0,1,1,0,1,0,1,0,1,1,0,1,0,1,0,1,1,0,1,0,1,0,1,0,1,1,0,1,0,1,1,0,1,0,0,1,0,1,0,1,0,1,1,0,1,0,1,1,0,0,1]}".trim());
224    }
225}