Skip to main content

epcis_models/
cbv.rs

1//! Core Business Vocabulary (CBV) standard enums and helper representations.
2
3use std::str::FromStr;
4use serde::{Deserialize, Deserializer, Serialize, Serializer};
5use strum_macros::{Display, EnumString, AsRefStr};
6
7/// Standard business step (bizStep) values as defined by GS1 CBV.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Display, EnumString, AsRefStr)]
9#[non_exhaustive]
10pub enum StandardBizStep {
11    /// accepting
12    #[strum(serialize = "urn:epcglobal:cbv:bizstep:accepting")]
13    Accepting,
14    /// arriving
15    #[strum(serialize = "urn:epcglobal:cbv:bizstep:arriving")]
16    Arriving,
17    /// assembling
18    #[strum(serialize = "urn:epcglobal:cbv:bizstep:assembling")]
19    Assembling,
20    /// collecting
21    #[strum(serialize = "urn:epcglobal:cbv:bizstep:collecting")]
22    Collecting,
23    /// commissioning
24    #[strum(serialize = "urn:epcglobal:cbv:bizstep:commissioning")]
25    Commissioning,
26    /// decommissioning
27    #[strum(serialize = "urn:epcglobal:cbv:bizstep:decommissioning")]
28    Decommissioning,
29    /// departing
30    #[strum(serialize = "urn:epcglobal:cbv:bizstep:departing")]
31    Departing,
32    /// destroying
33    #[strum(serialize = "urn:epcglobal:cbv:bizstep:destroying")]
34    Destroying,
35    /// disassembling
36    #[strum(serialize = "urn:epcglobal:cbv:bizstep:disassembling")]
37    Disassembling,
38    /// `entering_exiting`
39    #[strum(serialize = "urn:epcglobal:cbv:bizstep:entering_exiting")]
40    EnteringExiting,
41    /// holding
42    #[strum(serialize = "urn:epcglobal:cbv:bizstep:holding")]
43    Holding,
44    /// inspecting
45    #[strum(serialize = "urn:epcglobal:cbv:bizstep:inspecting")]
46    Inspecting,
47    /// installing
48    #[strum(serialize = "urn:epcglobal:cbv:bizstep:installing")]
49    Installing,
50    /// killing
51    #[strum(serialize = "urn:epcglobal:cbv:bizstep:killing")]
52    Killing,
53    /// loading
54    #[strum(serialize = "urn:epcglobal:cbv:bizstep:loading")]
55    Loading,
56    /// other
57    #[strum(serialize = "urn:epcglobal:cbv:bizstep:other")]
58    Other,
59    /// packing
60    #[strum(serialize = "urn:epcglobal:cbv:bizstep:packing")]
61    Packing,
62    /// picking
63    #[strum(serialize = "urn:epcglobal:cbv:bizstep:picking")]
64    Picking,
65    /// receiving
66    #[strum(serialize = "urn:epcglobal:cbv:bizstep:receiving")]
67    Receiving,
68    /// removing
69    #[strum(serialize = "urn:epcglobal:cbv:bizstep:removing")]
70    Removing,
71    /// repackaging
72    #[strum(serialize = "urn:epcglobal:cbv:bizstep:repackaging")]
73    Repackaging,
74    /// repairing
75    #[strum(serialize = "urn:epcglobal:cbv:bizstep:repairing")]
76    Repairing,
77    /// reselling
78    #[strum(serialize = "urn:epcglobal:cbv:bizstep:reselling")]
79    Reselling,
80    /// shipping
81    #[strum(serialize = "urn:epcglobal:cbv:bizstep:shipping")]
82    Shipping,
83    /// stocking
84    #[strum(serialize = "urn:epcglobal:cbv:bizstep:stocking")]
85    Stocking,
86    /// storing
87    #[strum(serialize = "urn:epcglobal:cbv:bizstep:storing")]
88    Storing,
89    /// transporting
90    #[strum(serialize = "urn:epcglobal:cbv:bizstep:transporting")]
91    Transporting,
92    /// unloading
93    #[strum(serialize = "urn:epcglobal:cbv:bizstep:unloading")]
94    Unloading,
95    /// unpacking
96    #[strum(serialize = "urn:epcglobal:cbv:bizstep:unpacking")]
97    Unpacking,
98    /// voiding
99    #[strum(serialize = "urn:epcglobal:cbv:bizstep:voiding")]
100    Voiding,
101}
102
103/// A business step that can either be a standard GS1 CBV value or a custom URI.
104#[derive(Debug, Clone, PartialEq, Eq, Hash)]
105pub enum BizStep {
106    /// A standard GS1 CBV business step.
107    Standard(StandardBizStep),
108    /// A custom business step URI.
109    Custom(String),
110}
111
112impl BizStep {
113    /// Returns the string representation of the business step.
114    #[must_use]
115    pub fn as_str(&self) -> &str {
116        match self {
117            BizStep::Standard(s) => s.as_ref(),
118            BizStep::Custom(c) => c.as_str(),
119        }
120    }
121}
122
123impl FromStr for BizStep {
124    type Err = std::convert::Infallible;
125
126    fn from_str(s: &str) -> Result<Self, Self::Err> {
127        match StandardBizStep::from_str(s) {
128            Ok(standard) => Ok(BizStep::Standard(standard)),
129            Err(_) => Ok(BizStep::Custom(s.to_string())),
130        }
131    }
132}
133
134impl Serialize for BizStep {
135    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
136    where
137        S: Serializer,
138    {
139        serializer.serialize_str(self.as_str())
140    }
141}
142
143impl<'de> Deserialize<'de> for BizStep {
144    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
145    where
146        D: Deserializer<'de>,
147    {
148        let s = String::deserialize(deserializer)?;
149        Ok(BizStep::from_str(&s).unwrap())
150    }
151}
152
153/// Standard disposition values as defined by GS1 CBV.
154#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Display, EnumString, AsRefStr)]
155#[non_exhaustive]
156pub enum StandardDisposition {
157    /// active
158    #[strum(serialize = "urn:epcglobal:cbv:disp:active")]
159    Active,
160    /// `container_closed`
161    #[strum(serialize = "urn:epcglobal:cbv:disp:container_closed")]
162    ContainerClosed,
163    /// `container_open`
164    #[strum(serialize = "urn:epcglobal:cbv:disp:container_open")]
165    ContainerOpen,
166    /// damaged
167    #[strum(serialize = "urn:epcglobal:cbv:disp:damaged")]
168    Damaged,
169    /// destroyed
170    #[strum(serialize = "urn:epcglobal:cbv:disp:destroyed")]
171    Destroyed,
172    /// dispensed
173    #[strum(serialize = "urn:epcglobal:cbv:disp:dispensed")]
174    Dispensed,
175    /// disposed
176    #[strum(serialize = "urn:epcglobal:cbv:disp:disposed")]
177    Disposed,
178    /// encoded
179    #[strum(serialize = "urn:epcglobal:cbv:disp:encoded")]
180    Encoded,
181    /// expired
182    #[strum(serialize = "urn:epcglobal:cbv:disp:expired")]
183    Expired,
184    /// `in_progress`
185    #[strum(serialize = "urn:epcglobal:cbv:disp:in_progress")]
186    InProgress,
187    /// `in_transit`
188    #[strum(serialize = "urn:epcglobal:cbv:disp:in_transit")]
189    InTransit,
190    /// inactive
191    #[strum(serialize = "urn:epcglobal:cbv:disp:inactive")]
192    Inactive,
193    /// `no_pedigree_match`
194    #[strum(serialize = "urn:epcglobal:cbv:disp:no_pedigree_match")]
195    NoPedigreeMatch,
196    /// `non_sellable`
197    #[strum(serialize = "urn:epcglobal:cbv:disp:non_sellable")]
198    NonSellable,
199    /// `non_disposed`
200    #[strum(serialize = "urn:epcglobal:cbv:disp:non_disposed")]
201    NonDisposed,
202    /// `parts_damaged`
203    #[strum(serialize = "urn:epcglobal:cbv:disp:parts_damaged")]
204    PartsDamaged,
205    /// `pedigree_match`
206    #[strum(serialize = "urn:epcglobal:cbv:disp:pedigree_match")]
207    PedigreeMatch,
208    /// recalled
209    #[strum(serialize = "urn:epcglobal:cbv:disp:recalled")]
210    Recalled,
211    /// `receiving_unconfirmed`
212    #[strum(serialize = "urn:epcglobal:cbv:disp:receiving_unconfirmed")]
213    ReceivingUnconfirmed,
214    /// reshelved
215    #[strum(serialize = "urn:epcglobal:cbv:disp:reshelved")]
216    Reshelved,
217    /// returned
218    #[strum(serialize = "urn:epcglobal:cbv:disp:returned")]
219    Returned,
220    /// `sellable_accessible`
221    #[strum(serialize = "urn:epcglobal:cbv:disp:sellable_accessible")]
222    SellableAccessible,
223    /// `sellable_not_accessible`
224    #[strum(serialize = "urn:epcglobal:cbv:disp:sellable_not_accessible")]
225    SellableNotAccessible,
226    /// stolen
227    #[strum(serialize = "urn:epcglobal:cbv:disp:stolen")]
228    Stolen,
229    /// unknown
230    #[strum(serialize = "urn:epcglobal:cbv:disp:unknown")]
231    Unknown,
232}
233
234/// A disposition that can either be a standard GS1 CBV value or a custom URI.
235#[derive(Debug, Clone, PartialEq, Eq, Hash)]
236pub enum Disposition {
237    /// A standard GS1 CBV disposition.
238    Standard(StandardDisposition),
239    /// A custom disposition URI.
240    Custom(String),
241}
242
243impl Disposition {
244    /// Returns the string representation of the disposition.
245    #[must_use]
246    pub fn as_str(&self) -> &str {
247        match self {
248            Disposition::Standard(s) => s.as_ref(),
249            Disposition::Custom(c) => c.as_str(),
250        }
251    }
252}
253
254impl FromStr for Disposition {
255    type Err = std::convert::Infallible;
256
257    fn from_str(s: &str) -> Result<Self, Self::Err> {
258        match StandardDisposition::from_str(s) {
259            Ok(standard) => Ok(Disposition::Standard(standard)),
260            Err(_) => Ok(Disposition::Custom(s.to_string())),
261        }
262    }
263}
264
265impl Serialize for Disposition {
266    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
267    where
268        S: Serializer,
269    {
270        serializer.serialize_str(self.as_str())
271    }
272}
273
274impl<'de> Deserialize<'de> for Disposition {
275    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
276    where
277        D: Deserializer<'de>,
278    {
279        let s = String::deserialize(deserializer)?;
280        Ok(Disposition::from_str(&s).unwrap())
281    }
282}