use crate::common::Result;
use crate::qrcode::decoder::{Version, VersionRef, MICRO_VERSIONS, VERSIONS, VERSION_DECODE_INFO};
use crate::Exceptions;
impl Version {
pub fn FromDimension(dimension: u32) -> Result<VersionRef> {
let isMicro = dimension < 21;
if dimension % Self::DimensionStep(isMicro) != 1 {
return Err(Exceptions::ILLEGAL_ARGUMENT);
}
Self::FromNumber(
(dimension - Self::DimensionOffset(isMicro)) / Self::DimensionStep(isMicro),
isMicro,
)
}
pub fn FromNumber(versionNumber: u32, is_micro: bool) -> Result<VersionRef> {
if versionNumber < 1 || versionNumber > (if is_micro { 4 } else { 40 }) {
return Err(Exceptions::ILLEGAL_ARGUMENT);
}
Ok(if is_micro {
&MICRO_VERSIONS[versionNumber as usize - 1]
} else {
&VERSIONS[versionNumber as usize - 1]
})
}
pub fn DimensionOfVersion(version: u32, is_micro: bool) -> u32 {
Self::DimensionOffset(is_micro) + Self::DimensionStep(is_micro) * version
}
pub fn DimensionOffset(is_micro: bool) -> u32 {
match is_micro {
true => 9,
false => 17,
}
}
pub fn DimensionStep(is_micro: bool) -> u32 {
match is_micro {
true => 2,
false => 4,
}
}
pub fn DecodeVersionInformation(versionBitsA: i32, versionBitsB: i32) -> Result<VersionRef> {
let mut bestDifference = u32::MAX;
let mut bestVersion = 0;
for (i, targetVersion) in VERSION_DECODE_INFO.into_iter().enumerate() {
if targetVersion == versionBitsA as u32 || targetVersion == versionBitsB as u32 {
return Self::getVersionForNumber(i as u32 + 7);
}
for bits in [versionBitsA, versionBitsB] {
let bitsDifference = ((bits as u32) ^ targetVersion).count_ones(); if bitsDifference < bestDifference {
bestVersion = i + 7;
bestDifference = bitsDifference;
}
}
}
if bestDifference <= 3 {
return Self::getVersionForNumber(bestVersion as u32);
}
Err(Exceptions::ILLEGAL_STATE)
}
pub const fn isMicroQRCode(&self) -> bool {
self.is_micro
}
}