1#![deny(missing_docs)]
4#![deny(unsafe_code)]
5#![warn(clippy::pedantic)]
6#![allow(clippy::module_name_repetitions)]
7
8use serde::{Deserialize, Serialize};
9use chrono::{DateTime, Utc};
10use crate::events::EPCISEvent;
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
14#[serde(rename_all = "camelCase")]
15pub struct EPCISDocument {
16 #[serde(rename = "@context")]
18 pub context: serde_json::Value,
19
20 #[serde(skip_serializing_if = "Option::is_none")]
22 pub id: Option<String>,
23
24 #[serde(rename = "type")]
26 pub r#type: String,
27
28 pub schema_version: String,
30
31 pub creation_date: DateTime<Utc>,
33
34 #[serde(skip_serializing_if = "Option::is_none")]
36 pub epcis_header: Option<EPCISHeader>,
37
38 pub epcis_body: EPCISBody,
40
41 #[serde(flatten)]
43 pub extensions: serde_json::Map<String, serde_json::Value>,
44}
45
46impl EPCISDocument {
47 #[must_use]
49 pub fn new(event_list: Vec<EPCISEvent>) -> Self {
50 Self {
51 context: serde_json::json!([
52 "https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld"
53 ]),
54 id: None,
55 r#type: "EPCISDocument".to_string(),
56 schema_version: "2.0".to_string(),
57 creation_date: Utc::now(),
58 epcis_header: None,
59 epcis_body: EPCISBody { event_list },
60 extensions: serde_json::Map::new(),
61 }
62 }
63}
64
65#[derive(Debug, Clone, Serialize, Deserialize)]
67#[serde(rename_all = "camelCase")]
68pub struct EPCISHeader {
69 #[serde(skip_serializing_if = "Option::is_none")]
71 pub epcis_master_data: Option<EPCISMasterData>,
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize)]
76#[serde(rename_all = "camelCase")]
77pub struct EPCISMasterData {
78 pub vocabulary_list: Vec<VocabularyElement>,
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize)]
84#[serde(rename_all = "camelCase")]
85pub struct VocabularyElement {
86 #[serde(rename = "type")]
88 pub r#type: String,
89 pub element_list: Vec<VocabularyElementList>,
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize)]
95#[serde(rename_all = "camelCase")]
96pub struct VocabularyElementList {
97 pub id: String,
99 #[serde(skip_serializing_if = "Option::is_none")]
101 pub attributes: Option<Vec<VocabularyAttribute>>,
102 #[serde(skip_serializing_if = "Option::is_none")]
104 pub children: Option<Vec<String>>,
105}
106
107#[derive(Debug, Clone, Serialize, Deserialize)]
109#[serde(rename_all = "camelCase")]
110pub struct VocabularyAttribute {
111 pub id: String,
113 pub value: serde_json::Value,
115}
116
117#[derive(Debug, Clone, Serialize, Deserialize)]
119#[serde(rename_all = "camelCase")]
120pub struct EPCISBody {
121 pub event_list: Vec<EPCISEvent>,
123}