Skip to main content

openleadr_wire/
ven.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use serde_with::{serde_as, skip_serializing_none, DefaultOnNull};
4use std::{fmt::Display, str::FromStr};
5use validator::Validate;
6
7use crate::{target::Target, values_map::ValuesMap, ClientId, Identifier, IdentifierError};
8
9/// Ven represents a client with the ven role.
10#[skip_serializing_none]
11#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Validate)]
12#[serde(rename_all = "camelCase")]
13pub struct Ven {
14    /// URL safe VTN assigned object ID.
15    pub id: VenId,
16    /// datetime in ISO 8601 format
17    #[serde(with = "crate::serde_rfc3339")]
18    pub created_date_time: DateTime<Utc>,
19    /// datetime in ISO 8601 format
20    #[serde(with = "crate::serde_rfc3339")]
21    pub modification_date_time: DateTime<Utc>,
22
23    #[serde(flatten)]
24    #[validate(nested)]
25    pub content: BlVenRequest,
26}
27
28#[skip_serializing_none]
29#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
30#[serde(rename_all = "SCREAMING_SNAKE_CASE", tag = "objectType")]
31pub enum VenRequest {
32    BlVenRequest(BlVenRequest),
33    VenVenRequest(VenVenRequest),
34}
35
36impl Validate for VenRequest {
37    fn validate(&self) -> Result<(), validator::ValidationErrors> {
38        match self {
39            VenRequest::BlVenRequest(x) => x.validate(),
40            VenRequest::VenVenRequest(x) => x.validate(),
41        }
42    }
43}
44
45impl VenRequest {
46    pub fn ven_name(&self) -> &str {
47        match self {
48            VenRequest::BlVenRequest(r) => &r.ven_name,
49            VenRequest::VenVenRequest(r) => &r.ven_name,
50        }
51    }
52
53    pub fn attributes(&self) -> Option<&[ValuesMap]> {
54        match self {
55            VenRequest::BlVenRequest(r) => r.attributes.as_deref(),
56            VenRequest::VenVenRequest(r) => r.attributes.as_deref(),
57        }
58    }
59}
60
61#[skip_serializing_none]
62#[serde_as]
63#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Validate)]
64#[serde(rename_all = "camelCase")]
65pub struct BlVenRequest {
66    #[serde(rename = "clientID")]
67    pub client_id: ClientId,
68    /// A list of targets.
69    #[serde(default)]
70    #[serde_as(deserialize_as = "DefaultOnNull")]
71    pub targets: Vec<Target>,
72    /// User generated identifier, may be VEN identifier provisioned during program enrollment.
73    #[serde(deserialize_with = "crate::string_within_range_inclusive::<1, 128, _>")]
74    pub ven_name: String,
75    /// A list of valuesMap objects describing attributes.
76    pub attributes: Option<Vec<ValuesMap>>,
77}
78
79#[skip_serializing_none]
80#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Validate)]
81#[serde(rename_all = "camelCase")]
82pub struct VenVenRequest {
83    /// User generated identifier, may be VEN identifier provisioned during program enrollment.
84    #[serde(deserialize_with = "crate::string_within_range_inclusive::<1, 128, _>")]
85    pub ven_name: String,
86    /// A list of valuesMap objects describing attributes.
87    pub attributes: Option<Vec<ValuesMap>>,
88}
89
90impl BlVenRequest {
91    pub fn new(
92        client_id: ClientId,
93        ven_name: String,
94        attributes: Option<Vec<ValuesMap>>,
95        targets: Vec<Target>,
96    ) -> Self {
97        Self {
98            client_id,
99            ven_name,
100            attributes,
101            targets,
102        }
103    }
104}
105
106#[derive(
107    Clone, Debug, PartialEq, Serialize, Deserialize, Hash, Eq, PartialOrd, Ord, sqlx::Type,
108)]
109#[serde(transparent)]
110#[sqlx(transparent)]
111pub struct VenId(pub(crate) Identifier);
112
113impl Display for VenId {
114    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
115        write!(f, "{}", self.0)
116    }
117}
118
119impl VenId {
120    pub fn as_str(&self) -> &str {
121        self.0.as_str()
122    }
123
124    pub fn new(identifier: &str) -> Option<Self> {
125        Some(Self(identifier.parse().ok()?))
126    }
127}
128
129impl FromStr for VenId {
130    type Err = IdentifierError;
131
132    fn from_str(s: &str) -> Result<Self, Self::Err> {
133        Ok(Self(s.parse()?))
134    }
135}