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#[skip_serializing_none]
11#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Validate)]
12#[serde(rename_all = "camelCase")]
13pub struct Ven {
14 pub id: VenId,
16 #[serde(with = "crate::serde_rfc3339")]
18 pub created_date_time: DateTime<Utc>,
19 #[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 #[serde(default)]
70 #[serde_as(deserialize_as = "DefaultOnNull")]
71 pub targets: Vec<Target>,
72 #[serde(deserialize_with = "crate::string_within_range_inclusive::<1, 128, _>")]
74 pub ven_name: String,
75 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 #[serde(deserialize_with = "crate::string_within_range_inclusive::<1, 128, _>")]
85 pub ven_name: String,
86 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}