1use std::{collections::HashMap, fmt};
18
19use crate::{
20 BarcodeFormat, MetadataDictionary, Point, RXingResultMetadataType, RXingResultMetadataValue,
21 common::cpp_essentials::DecoderResult,
22};
23
24pub type RXingResultMetaDataDictionary = HashMap<RXingResultMetadataType, RXingResultMetadataValue>;
25
26#[cfg(feature = "serde")]
27use serde::{Deserialize, Serialize};
28
29#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
35#[derive(Clone, Debug, PartialEq, Eq)]
36pub struct RXingResult {
37 text: String,
38 rawBytes: Vec<u8>,
39 numBits: usize,
40 resultPoints: Vec<Point>,
41 format: BarcodeFormat,
42 resultMetadata: RXingResultMetaDataDictionary,
43 timestamp: u128,
44 line_count: usize,
45}
46impl RXingResult {
47 pub fn new(
48 text: &str,
49 rawBytes: Vec<u8>,
50 resultPoints: Vec<Point>,
51 format: BarcodeFormat,
52 ) -> Self {
53 Self::new_timestamp(
54 text,
55 rawBytes,
56 resultPoints,
57 format,
58 chrono::Utc::now().timestamp_millis() as u128,
59 )
60 }
61
62 pub fn new_timestamp(
63 text: &str,
64 rawBytes: Vec<u8>,
65 resultPoints: Vec<Point>,
66 format: BarcodeFormat,
67 timestamp: u128,
68 ) -> Self {
69 let l = rawBytes.len();
70 Self::new_complex(text, rawBytes, 8 * l, resultPoints, format, timestamp)
71 }
72
73 pub fn new_complex(
74 text: &str,
75 rawBytes: Vec<u8>,
76 numBits: usize,
77 resultPoints: Vec<Point>,
78 format: BarcodeFormat,
79 timestamp: u128,
80 ) -> Self {
81 Self {
82 text: text.to_owned(),
83 rawBytes,
84 numBits,
85 resultPoints,
86 format,
87 resultMetadata: HashMap::new(),
88 timestamp,
89 line_count: 0,
90 }
91 }
92
93 pub fn with_point(self, points: Vec<Point>) -> Self {
94 Self {
95 text: self.text,
96 rawBytes: self.rawBytes,
97 numBits: self.numBits,
98 resultPoints: points,
99 format: self.format,
100 resultMetadata: self.resultMetadata,
101 timestamp: self.timestamp,
102 line_count: self.line_count,
103 }
104 }
105
106 pub fn with_decoder_result<T>(
107 res: DecoderResult<T>,
108 resultPoints: &[Point],
109 format: BarcodeFormat,
110 ) -> Self
111 where
112 T: Copy + Clone + Default + Eq + PartialEq,
113 {
114 let mut new_res = Self::new(
115 &res.text(),
116 res.content().bytes().to_vec(),
117 resultPoints.to_vec(),
118 format,
119 );
120
121 let mut meta_data = MetadataDictionary::new();
122 meta_data.insert(
123 RXingResultMetadataType::ERROR_CORRECTION_LEVEL,
124 RXingResultMetadataValue::ErrorCorrectionLevel(res.ecLevel().to_owned()),
125 );
126 meta_data.insert(
127 RXingResultMetadataType::STRUCTURED_APPEND_PARITY,
128 RXingResultMetadataValue::StructuredAppendParity(res.structuredAppend().count),
129 );
130 meta_data.insert(
131 RXingResultMetadataType::STRUCTURED_APPEND_SEQUENCE,
132 RXingResultMetadataValue::StructuredAppendSequence(res.structuredAppend().index),
133 );
134 meta_data.insert(
135 RXingResultMetadataType::SYMBOLOGY_IDENTIFIER,
136 RXingResultMetadataValue::SymbologyIdentifier(res.symbologyIdentifier()),
137 );
138
139 new_res.putAllMetadata(meta_data);
140
141 new_res
142 }
143
144 pub fn getText(&self) -> &str {
148 &self.text
149 }
150
151 pub fn getRawBytes(&self) -> &[u8] {
155 &self.rawBytes
156 }
157
158 pub fn getNumBits(&self) -> usize {
163 self.numBits
164 }
165
166 pub fn getPoints(&self) -> &[Point] {
172 &self.resultPoints
173 }
174
175 pub fn getPointsMut(&mut self) -> &mut [Point] {
176 &mut self.resultPoints
177 }
178
179 pub fn getRXingResultPoints(&self) -> &[Point] {
181 &self.resultPoints
182 }
183
184 pub fn getRXingResultPointsMut(&mut self) -> &mut [Point] {
186 &mut self.resultPoints
187 }
188
189 pub fn getBarcodeFormat(&self) -> &BarcodeFormat {
193 &self.format
194 }
195
196 pub fn getRXingResultMetadata(&self) -> &RXingResultMetaDataDictionary {
202 &self.resultMetadata
203 }
204
205 pub fn putMetadata(
206 &mut self,
207 md_type: RXingResultMetadataType,
208 value: RXingResultMetadataValue,
209 ) {
210 self.resultMetadata.insert(md_type, value);
211 }
212
213 pub fn putAllMetadata(&mut self, metadata: RXingResultMetaDataDictionary) {
214 if self.resultMetadata.is_empty() {
215 let _ = std::mem::replace(&mut self.resultMetadata, metadata);
216 } else {
217 for (key, value) in metadata.into_iter() {
218 self.resultMetadata.insert(key, value);
219 }
220 }
221 }
222
223 pub fn addPoints(&mut self, newPoints: &mut Vec<Point>) {
224 if !newPoints.is_empty() {
225 self.resultPoints.append(newPoints);
226 }
227 }
228
229 pub fn getTimestamp(&self) -> u128 {
230 self.timestamp
231 }
232
233 pub fn line_count(&self) -> usize {
234 self.line_count
235 }
236
237 pub fn set_line_count(&mut self, lc: usize) {
238 self.line_count = lc
239 }
240
241 pub fn replace_points(&mut self, points: Vec<Point>) {
242 self.resultPoints = points
243 }
244}
245
246impl fmt::Display for RXingResult {
247 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
248 write!(f, "{}", self.text)
249 }
250}