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
109
110
111
112
113
use crate::error::{Result, UnimplementedError};
use num_enum::TryFromPrimitive;
use std::convert::TryFrom;
pub mod gid;
pub mod sgtin;
pub mod sscc;
pub mod tid;
#[derive(Debug, Eq, PartialEq, TryFromPrimitive, Copy, Clone)]
#[repr(u8)]
#[allow(clippy::upper_case_acronyms)]
enum EPCBinaryHeader {
Unprogrammed = 0x00,
GTDI96 = 0x2C,
GSRN96 = 0x2D,
GSRNP = 0x2E,
USDoD96 = 0x2F,
SGITN96 = 0x30,
SSCC96 = 0x31,
SGLN96 = 0x32,
GRAI96 = 0x33,
GIAI96 = 0x34,
GID96 = 0x35,
SGITN198 = 0x36,
GRAI170 = 0x37,
GIAI202 = 0x38,
SGLN195 = 0x39,
GTDI113 = 0x3A,
ADIVAR = 0x3B,
CPI96 = 0x3C,
CPIVAR = 0x3D,
GDTI174 = 0x3E,
SGCN96 = 0x3F,
ITIP110 = 0x40,
ITIP212 = 0x41,
}
pub trait EPC {
fn to_uri(&self) -> String;
fn to_tag_uri(&self) -> String;
fn get_value(&self) -> EPCValue;
}
#[derive(PartialEq, Debug)]
pub struct Unprogrammed {
pub data: Vec<u8>,
}
impl EPC for Unprogrammed {
fn to_uri(&self) -> String {
"urn:epc:id:unprogrammed".to_string()
}
fn to_tag_uri(&self) -> String {
"urn:epc:tag:unprogrammed".to_string()
}
fn get_value(&self) -> EPCValue {
EPCValue::Unprogrammed(self)
}
}
#[derive(PartialEq, Debug)]
pub enum EPCValue<'a> {
Unprogrammed(&'a Unprogrammed),
SGTIN96(&'a sgtin::SGTIN96),
SGTIN198(&'a sgtin::SGTIN198),
SSCC96(&'a sscc::SSCC96),
GID96(&'a gid::GID96),
}
fn take_header(data: &[u8]) -> Result<(&[u8], EPCBinaryHeader)> {
let header = EPCBinaryHeader::try_from(data[0])?;
Ok((&data[1..], header))
}
pub fn decode_binary(data: &[u8]) -> Result<Box<dyn EPC>> {
let (data, header) = take_header(data)?;
Ok(match header {
EPCBinaryHeader::GID96 => gid::decode_gid96(data)?,
EPCBinaryHeader::SGITN96 => sgtin::decode_sgtin96(data)?,
EPCBinaryHeader::SGITN198 => sgtin::decode_sgtin198(data)?,
EPCBinaryHeader::SSCC96 => sscc::decode_sscc96(data)?,
EPCBinaryHeader::Unprogrammed => Box::new(Unprogrammed {
data: data.to_vec(),
}) as Box<dyn EPC>,
_unimplemented => {
return Err(Box::new(UnimplementedError()));
}
})
}