use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use serde_with::{DefaultOnNull, serde_as, skip_serializing_none};
use std::{fmt::Display, str::FromStr};
use validator::Validate;
use crate::{ClientId, Identifier, IdentifierError, target::Target, values_map::ValuesMap};
#[skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Validate)]
#[serde(rename_all = "camelCase")]
pub struct Ven {
pub id: VenId,
#[serde(with = "crate::serde_rfc3339")]
pub created_date_time: DateTime<Utc>,
#[serde(with = "crate::serde_rfc3339")]
pub modification_date_time: DateTime<Utc>,
#[serde(flatten)]
#[validate(nested)]
pub content: BlVenRequest,
}
#[skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE", tag = "objectType")]
pub enum VenRequest {
BlVenRequest(BlVenRequest),
VenVenRequest(VenVenRequest),
}
impl Validate for VenRequest {
fn validate(&self) -> Result<(), validator::ValidationErrors> {
match self {
VenRequest::BlVenRequest(x) => x.validate(),
VenRequest::VenVenRequest(x) => x.validate(),
}
}
}
impl VenRequest {
pub fn ven_name(&self) -> &str {
match self {
VenRequest::BlVenRequest(r) => &r.ven_name,
VenRequest::VenVenRequest(r) => &r.ven_name,
}
}
pub fn attributes(&self) -> Option<&[ValuesMap]> {
match self {
VenRequest::BlVenRequest(r) => r.attributes.as_deref(),
VenRequest::VenVenRequest(r) => r.attributes.as_deref(),
}
}
}
#[skip_serializing_none]
#[serde_as]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Validate)]
#[serde(rename_all = "camelCase")]
pub struct BlVenRequest {
#[serde(rename = "clientID")]
pub client_id: ClientId,
#[serde(default)]
#[serde_as(deserialize_as = "DefaultOnNull")]
pub targets: Vec<Target>,
#[serde(deserialize_with = "crate::string_within_range_inclusive::<1, 128, _>")]
pub ven_name: String,
pub attributes: Option<Vec<ValuesMap>>,
}
#[skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Validate)]
#[serde(rename_all = "camelCase")]
pub struct VenVenRequest {
#[serde(deserialize_with = "crate::string_within_range_inclusive::<1, 128, _>")]
pub ven_name: String,
pub attributes: Option<Vec<ValuesMap>>,
}
impl BlVenRequest {
pub fn new(
client_id: ClientId,
ven_name: String,
attributes: Option<Vec<ValuesMap>>,
targets: Vec<Target>,
) -> Self {
Self {
client_id,
ven_name,
attributes,
targets,
}
}
}
#[derive(
Clone, Debug, PartialEq, Serialize, Deserialize, Hash, Eq, PartialOrd, Ord, sqlx::Type,
)]
#[serde(transparent)]
#[sqlx(transparent)]
pub struct VenId(pub(crate) Identifier);
impl Display for VenId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl VenId {
pub fn as_str(&self) -> &str {
self.0.as_str()
}
pub fn new(identifier: &str) -> Option<Self> {
Some(Self(identifier.parse().ok()?))
}
}
impl FromStr for VenId {
type Err = IdentifierError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(s.parse()?))
}
}