1use crate::encoding::{BitMatrix, Encoded, LinearPattern, Postal4Pattern, StackedPattern};
4use crate::error::Error;
5use crate::options::Options;
6use crate::symbology::Symbology;
7
8mod png;
9mod svg;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub enum Format {
14 Svg,
16 Png,
18}
19
20pub fn render_svg(symbology: Symbology, data: &str, opts: &Options) -> Result<String, Error> {
34 let encoded = symbology.encode(data, opts)?;
35 Ok(match encoded {
36 Encoded::Linear(p) => svg::render_linear(&p, opts),
37 Encoded::Matrix(m) => svg::render_matrix(&m, opts),
38 Encoded::Postal4State(p) => svg::render_postal4(&p, opts),
39 Encoded::Stacked(p) => svg::render_stacked(&p, opts),
40 Encoded::Dots(d) => svg::render_dots(&d, opts),
41 Encoded::Hex(s) => svg::render_hex(&s, opts),
42 Encoded::ColorMatrix(m) => svg::render_color_matrix(&m, opts),
43 })
44}
45
46pub fn render_png(symbology: Symbology, data: &str, opts: &Options) -> Result<Vec<u8>, Error> {
60 let encoded = symbology.encode(data, opts)?;
61 match encoded {
62 Encoded::Linear(p) => png::render_linear(&p, opts),
63 Encoded::Matrix(m) => png::render_matrix(&m, opts),
64 Encoded::Postal4State(p) => png::render_postal4(&p, opts),
65 Encoded::Stacked(p) => png::render_stacked(&p, opts),
66 Encoded::Dots(d) => png::render_dots(&d, opts),
67 Encoded::Hex(s) => png::render_hex(&s, opts),
68 Encoded::ColorMatrix(m) => png::render_color_matrix(&m, opts),
69 }
70}
71
72#[allow(dead_code)]
73pub(crate) fn iter_linear_runs(p: &LinearPattern) -> impl Iterator<Item = (u32, bool)> + '_ {
74 p.bars
75 .iter()
76 .enumerate()
77 .map(|(i, &width)| (u32::from(width), i % 2 == 0))
78}
79
80#[allow(dead_code)]
81pub(crate) fn matrix_dimensions(m: &BitMatrix) -> (usize, usize) {
82 (m.width(), m.height())
83}
84
85#[allow(dead_code)]
86pub(crate) fn postal4_bar_count(p: &Postal4Pattern) -> usize {
87 p.len()
88}
89
90#[allow(dead_code)]
91pub(crate) fn stacked_row_count(p: &StackedPattern) -> usize {
92 p.height_rows()
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[test]
109 fn helper_accessors_return_expected_values() {
110 use crate::encoding::{Bar4State, LinearPattern, Postal4Pattern};
111
112 let lp = LinearPattern {
115 bars: vec![1, 2, 3, 4],
116 text: None,
117 };
118 let runs: Vec<(u32, bool)> = iter_linear_runs(&lp).collect();
119 assert_eq!(
120 runs,
121 vec![(1, true), (2, false), (3, true), (4, false)],
122 "bar/space alternation must start with bar (i==0)"
123 );
124
125 let m = BitMatrix::new(7, 4);
127 assert_eq!(matrix_dimensions(&m), (7, 4));
128
129 let p = Postal4Pattern {
131 bars: vec![Bar4State::Full; 5],
132 text: None,
133 };
134 assert_eq!(postal4_bar_count(&p), 5);
135
136 let sp = StackedPattern::new(
138 vec![
139 LinearPattern {
140 bars: vec![1, 2, 3],
141 text: None,
142 },
143 LinearPattern {
144 bars: vec![3, 2, 1],
145 text: None,
146 },
147 ],
148 None,
149 )
150 .unwrap();
151 assert_eq!(stacked_row_count(&sp), 2);
152 }
153}