use std::{collections::HashMap, fmt};
use crate::{
common::cpp_essentials::DecoderResult, BarcodeFormat, MetadataDictionary, Point,
RXingResultMetadataType, RXingResultMetadataValue,
};
pub type RXingResultMetaDataDictionary = HashMap<RXingResultMetadataType, RXingResultMetadataValue>;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RXingResult {
text: String,
rawBytes: Vec<u8>,
numBits: usize,
resultPoints: Vec<Point>,
format: BarcodeFormat,
resultMetadata: RXingResultMetaDataDictionary,
timestamp: u128,
line_count: usize,
}
impl RXingResult {
pub fn new(
text: &str,
rawBytes: Vec<u8>,
resultPoints: Vec<Point>,
format: BarcodeFormat,
) -> Self {
Self::new_timestamp(
text,
rawBytes,
resultPoints,
format,
chrono::Utc::now().timestamp_millis() as u128,
)
}
pub fn new_timestamp(
text: &str,
rawBytes: Vec<u8>,
resultPoints: Vec<Point>,
format: BarcodeFormat,
timestamp: u128,
) -> Self {
let l = rawBytes.len();
Self::new_complex(text, rawBytes, 8 * l, resultPoints, format, timestamp)
}
pub fn new_complex(
text: &str,
rawBytes: Vec<u8>,
numBits: usize,
resultPoints: Vec<Point>,
format: BarcodeFormat,
timestamp: u128,
) -> Self {
Self {
text: text.to_owned(),
rawBytes,
numBits,
resultPoints,
format,
resultMetadata: HashMap::new(),
timestamp,
line_count: 0,
}
}
pub fn with_point(self, points: Vec<Point>) -> Self {
Self {
text: self.text,
rawBytes: self.rawBytes,
numBits: self.numBits,
resultPoints: points,
format: self.format,
resultMetadata: self.resultMetadata,
timestamp: self.timestamp,
line_count: self.line_count,
}
}
pub fn with_decoder_result<T>(
res: DecoderResult<T>,
resultPoints: &[Point],
format: BarcodeFormat,
) -> Self
where
T: Copy + Clone + Default + Eq + PartialEq,
{
let mut new_res = Self::new(
&res.text(),
res.content().bytes().to_vec(),
resultPoints.to_vec(),
format,
);
let mut meta_data = MetadataDictionary::new();
meta_data.insert(
RXingResultMetadataType::ERROR_CORRECTION_LEVEL,
RXingResultMetadataValue::ErrorCorrectionLevel(res.ecLevel().to_owned()),
);
meta_data.insert(
RXingResultMetadataType::STRUCTURED_APPEND_PARITY,
RXingResultMetadataValue::StructuredAppendParity(res.structuredAppend().count),
);
meta_data.insert(
RXingResultMetadataType::STRUCTURED_APPEND_SEQUENCE,
RXingResultMetadataValue::StructuredAppendSequence(res.structuredAppend().index),
);
meta_data.insert(
RXingResultMetadataType::SYMBOLOGY_IDENTIFIER,
RXingResultMetadataValue::SymbologyIdentifier(res.symbologyIdentifier()),
);
new_res.putAllMetadata(meta_data);
new_res
}
pub fn getText(&self) -> &str {
&self.text
}
pub fn getRawBytes(&self) -> &[u8] {
&self.rawBytes
}
pub fn getNumBits(&self) -> usize {
self.numBits
}
pub fn getPoints(&self) -> &[Point] {
&self.resultPoints
}
pub fn getPointsMut(&mut self) -> &mut [Point] {
&mut self.resultPoints
}
pub fn getRXingResultPoints(&self) -> &[Point] {
&self.resultPoints
}
pub fn getRXingResultPointsMut(&mut self) -> &mut [Point] {
&mut self.resultPoints
}
pub fn getBarcodeFormat(&self) -> &BarcodeFormat {
&self.format
}
pub fn getRXingResultMetadata(&self) -> &RXingResultMetaDataDictionary {
&self.resultMetadata
}
pub fn putMetadata(
&mut self,
md_type: RXingResultMetadataType,
value: RXingResultMetadataValue,
) {
self.resultMetadata.insert(md_type, value);
}
pub fn putAllMetadata(&mut self, metadata: RXingResultMetaDataDictionary) {
if self.resultMetadata.is_empty() {
let _ = std::mem::replace(&mut self.resultMetadata, metadata);
} else {
for (key, value) in metadata.into_iter() {
self.resultMetadata.insert(key, value);
}
}
}
pub fn addPoints(&mut self, newPoints: &mut Vec<Point>) {
if !newPoints.is_empty() {
self.resultPoints.append(newPoints);
}
}
pub fn getTimestamp(&self) -> u128 {
self.timestamp
}
pub fn line_count(&self) -> usize {
self.line_count
}
pub fn set_line_count(&mut self, lc: usize) {
self.line_count = lc
}
pub fn replace_points(&mut self, points: Vec<Point>) {
self.resultPoints = points
}
}
impl fmt::Display for RXingResult {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.text)
}
}