1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use crate::checksum::gs1_checksum;
use crate::epc::{EPCValue, EPC};
use crate::error::{ParseError, Result};
use crate::util::{extract_indicator, zero_pad};
use crate::{ApplicationIdentifier, GS1};
use bitreader::BitReader;
#[derive(PartialEq, Debug)]
pub struct SSCC96 {
pub filter: u8,
pub partition: u8,
pub indicator: u8,
pub company: u64,
pub serial: u64,
}
impl EPC for SSCC96 {
fn to_uri(&self) -> String {
format!(
"urn:epc:id:sscc:{}.{}{}",
zero_pad(self.company.to_string(), company_digits(self.partition)),
self.indicator,
zero_pad(self.serial.to_string(), item_digits(self.partition) - 1)
)
}
fn to_tag_uri(&self) -> String {
format!(
"urn:epc:tag:sscc-96:{}.{}.{}{}",
self.filter,
zero_pad(self.company.to_string(), company_digits(self.partition)),
self.indicator,
zero_pad(self.serial.to_string(), item_digits(self.partition) - 1)
)
}
fn get_value(&self) -> EPCValue {
EPCValue::SSCC96(self)
}
}
impl GS1 for SSCC96 {
fn to_gs1(&self) -> String {
let element_string = format!(
"{}{}{}",
self.indicator,
zero_pad(self.company.to_string(), company_digits(self.partition)),
zero_pad(self.serial.to_string(), item_digits(self.partition) - 1)
);
format!(
"({:0>2}) {}{}",
ApplicationIdentifier::SSCC as u16,
element_string,
gs1_checksum(&element_string)
)
}
}
fn company_digits(partition: u8) -> usize {
12 - partition as usize
}
fn item_digits(partition: u8) -> usize {
17 - company_digits(partition)
}
fn partition_bits(partition: u8) -> Result<(u8, u8)> {
Ok(match partition {
0 => (40, 18),
1 => (37, 21),
2 => (34, 24),
3 => (30, 28),
4 => (27, 31),
5 => (24, 34),
6 => (20, 48),
_ => {
return Err(Box::new(ParseError()));
}
})
}
pub(super) fn decode_sscc96(data: &[u8]) -> Result<Box<dyn EPC>> {
let mut reader = BitReader::new(data);
let filter = reader.read_u8(3)?;
let partition = reader.read_u8(3)?;
let (company_bits, serial_bits) = partition_bits(partition)?;
let company = reader.read_u64(company_bits)?;
let serial = reader.read_u64(serial_bits)?;
let (serial, indicator) = extract_indicator(serial, item_digits(partition))?;
Ok(Box::new(SSCC96 {
filter,
partition,
indicator,
company,
serial,
}))
}