use super::cads::CADSKind;
use super::enums::InfrastructureType;
use super::table::{ContactDetails, SlaProperty};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use uuid::Uuid;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub enum CrowsfeetCardinality {
OneToOne,
OneToMany,
ZeroOrOne,
ZeroOrMany,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct System {
pub id: Uuid,
pub name: String,
pub infrastructure_type: InfrastructureType,
pub domain_id: Uuid,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(default)]
pub endpoints: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub owner: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sla: Option<Vec<SlaProperty>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub contact_details: Option<ContactDetails>,
#[serde(skip_serializing_if = "Option::is_none")]
pub notes: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<String>,
#[serde(default)]
pub metadata: HashMap<String, serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub created_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub updated_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct SystemConnection {
pub id: Uuid,
pub source_system_id: Uuid,
pub target_system_id: Uuid,
pub connection_type: String,
#[serde(default)]
pub bidirectional: bool,
#[serde(default)]
pub metadata: HashMap<String, serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub created_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub updated_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct SharedNodeReference {
pub domain_id: Uuid,
pub node_id: Uuid,
pub node_version: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct CADSNode {
pub id: Uuid,
pub system_id: Uuid,
#[serde(skip_serializing_if = "Option::is_none")]
pub cads_asset_id: Option<Uuid>,
pub kind: CADSKind,
#[serde(skip_serializing_if = "Option::is_none")]
pub shared_reference: Option<SharedNodeReference>,
#[serde(default)]
pub custom_metadata: Vec<HashMap<String, serde_json::Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub created_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub updated_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ODCSNode {
pub id: Uuid,
pub system_id: Uuid,
#[serde(skip_serializing_if = "Option::is_none")]
pub table_id: Option<Uuid>,
pub role: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub shared_reference: Option<SharedNodeReference>,
#[serde(default)]
pub custom_metadata: Vec<HashMap<String, serde_json::Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub created_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub updated_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct NodeConnection {
pub id: Uuid,
pub source_node_id: Uuid,
pub target_node_id: Uuid,
pub cardinality: CrowsfeetCardinality,
pub relationship_type: String,
#[serde(default)]
pub metadata: HashMap<String, serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub created_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub updated_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Domain {
pub id: Uuid,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(default)]
pub systems: Vec<System>,
#[serde(default)]
pub cads_nodes: Vec<CADSNode>,
#[serde(default)]
pub odcs_nodes: Vec<ODCSNode>,
#[serde(default)]
pub system_connections: Vec<SystemConnection>,
#[serde(default)]
pub node_connections: Vec<NodeConnection>,
#[serde(skip_serializing_if = "Option::is_none")]
pub created_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub updated_at: Option<DateTime<Utc>>,
}
impl Domain {
pub fn new(name: String) -> Self {
Self {
id: Uuid::new_v4(),
name,
description: None,
systems: Vec::new(),
cads_nodes: Vec::new(),
odcs_nodes: Vec::new(),
system_connections: Vec::new(),
node_connections: Vec::new(),
created_at: Some(chrono::Utc::now()),
updated_at: Some(chrono::Utc::now()),
}
}
pub fn add_system(&mut self, mut system: System) {
system.domain_id = self.id;
system.created_at = Some(chrono::Utc::now());
system.updated_at = Some(chrono::Utc::now());
self.systems.push(system);
self.updated_at = Some(chrono::Utc::now());
}
pub fn add_cads_node(&mut self, mut node: CADSNode) {
node.created_at = Some(chrono::Utc::now());
node.updated_at = Some(chrono::Utc::now());
self.cads_nodes.push(node);
self.updated_at = Some(chrono::Utc::now());
}
pub fn add_odcs_node(&mut self, mut node: ODCSNode) {
node.created_at = Some(chrono::Utc::now());
node.updated_at = Some(chrono::Utc::now());
self.odcs_nodes.push(node);
self.updated_at = Some(chrono::Utc::now());
}
pub fn add_system_connection(&mut self, mut connection: SystemConnection) {
connection.created_at = Some(chrono::Utc::now());
connection.updated_at = Some(chrono::Utc::now());
self.system_connections.push(connection);
self.updated_at = Some(chrono::Utc::now());
}
pub fn add_node_connection(&mut self, mut connection: NodeConnection) {
connection.created_at = Some(chrono::Utc::now());
connection.updated_at = Some(chrono::Utc::now());
self.node_connections.push(connection);
self.updated_at = Some(chrono::Utc::now());
}
pub fn from_yaml(yaml_content: &str) -> Result<Self, serde_yaml::Error> {
serde_yaml::from_str(yaml_content)
}
pub fn to_yaml(&self) -> Result<String, serde_yaml::Error> {
serde_yaml::to_string(self)
}
}
impl System {
pub fn new(name: String, infrastructure_type: InfrastructureType, domain_id: Uuid) -> Self {
Self {
id: Uuid::new_v4(),
name,
infrastructure_type,
domain_id,
description: None,
endpoints: Vec::new(),
owner: None,
sla: None,
contact_details: None,
notes: None,
version: None,
metadata: HashMap::new(),
created_at: Some(chrono::Utc::now()),
updated_at: Some(chrono::Utc::now()),
}
}
}
impl CADSNode {
pub fn new_local(system_id: Uuid, cads_asset_id: Uuid, kind: CADSKind) -> Self {
Self {
id: Uuid::new_v4(),
system_id,
cads_asset_id: Some(cads_asset_id),
kind,
shared_reference: None,
custom_metadata: Vec::new(),
created_at: Some(chrono::Utc::now()),
updated_at: Some(chrono::Utc::now()),
}
}
pub fn new_shared(
system_id: Uuid,
kind: CADSKind,
shared_reference: SharedNodeReference,
) -> Self {
Self {
id: Uuid::new_v4(),
system_id,
cads_asset_id: None,
kind,
shared_reference: Some(shared_reference),
custom_metadata: Vec::new(),
created_at: Some(chrono::Utc::now()),
updated_at: Some(chrono::Utc::now()),
}
}
}
impl ODCSNode {
pub fn new_local(system_id: Uuid, table_id: Uuid, role: String) -> Self {
Self {
id: Uuid::new_v4(),
system_id,
table_id: Some(table_id),
role,
shared_reference: None,
custom_metadata: Vec::new(),
created_at: Some(chrono::Utc::now()),
updated_at: Some(chrono::Utc::now()),
}
}
pub fn new_shared(
system_id: Uuid,
role: String,
shared_reference: SharedNodeReference,
) -> Self {
Self {
id: Uuid::new_v4(),
system_id,
table_id: None,
role,
shared_reference: Some(shared_reference),
custom_metadata: Vec::new(),
created_at: Some(chrono::Utc::now()),
updated_at: Some(chrono::Utc::now()),
}
}
}