#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum C4Element {
Person(Person),
SoftwareSystem(SoftwareSystem),
Container(Container),
Component(Component),
Relationship(Relationship),
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Person {
pub name: String,
pub description: Option<String>,
}
impl Person {
pub fn new(name: impl Into<String>) -> Self {
Self { name: name.into(), description: None }
}
pub fn with_description(mut self, description: impl Into<String>) -> Self {
self.description = Some(description.into());
self
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SoftwareSystem {
pub name: String,
pub description: Option<String>,
}
impl SoftwareSystem {
pub fn new(name: impl Into<String>) -> Self {
Self { name: name.into(), description: None }
}
pub fn with_description(mut self, description: impl Into<String>) -> Self {
self.description = Some(description.into());
self
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Container {
pub name: String,
pub technology: Option<String>,
pub description: Option<String>,
}
impl Container {
pub fn new(name: impl Into<String>) -> Self {
Self { name: name.into(), technology: None, description: None }
}
pub fn with_technology(mut self, technology: impl Into<String>) -> Self {
self.technology = Some(technology.into());
self
}
pub fn with_description(mut self, description: impl Into<String>) -> Self {
self.description = Some(description.into());
self
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Component {
pub name: String,
pub technology: Option<String>,
pub description: Option<String>,
}
impl Component {
pub fn new(name: impl Into<String>) -> Self {
Self { name: name.into(), technology: None, description: None }
}
pub fn with_technology(mut self, technology: impl Into<String>) -> Self {
self.technology = Some(technology.into());
self
}
pub fn with_description(mut self, description: impl Into<String>) -> Self {
self.description = Some(description.into());
self
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Relationship {
pub source: String,
pub target: String,
pub label: String,
pub technology: Option<String>,
}
impl Relationship {
pub fn new(source: impl Into<String>, target: impl Into<String>, label: impl Into<String>) -> Self {
Self { source: source.into(), target: target.into(), label: label.into(), technology: None }
}
pub fn with_technology(mut self, technology: impl Into<String>) -> Self {
self.technology = Some(technology.into());
self
}
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct C4Diagram {
pub elements: Vec<C4Element>,
}
impl C4Diagram {
pub fn new() -> Self {
Self::default()
}
pub fn with_element(mut self, element: impl Into<C4Element>) -> Self {
self.elements.push(element.into());
self
}
pub fn person(self, name: impl Into<String>, description: impl Into<String>) -> Self {
self.with_element(Person::new(name).with_description(description))
}
pub fn software_system(self, name: impl Into<String>, description: impl Into<String>) -> Self {
self.with_element(SoftwareSystem::new(name).with_description(description))
}
pub fn container(self, name: impl Into<String>, technology: impl Into<String>, description: impl Into<String>) -> Self {
self.with_element(Container::new(name).with_technology(technology).with_description(description))
}
pub fn component(self, name: impl Into<String>, technology: impl Into<String>, description: impl Into<String>) -> Self {
self.with_element(Component::new(name).with_technology(technology).with_description(description))
}
pub fn rel(self, source: impl Into<String>, target: impl Into<String>, label: impl Into<String>) -> Self {
self.with_element(Relationship::new(source, target, label))
}
pub fn rel_with_tech(self, source: impl Into<String>, target: impl Into<String>, label: impl Into<String>, technology: impl Into<String>) -> Self {
self.with_element(Relationship::new(source, target, label).with_technology(technology))
}
}
impl From<Person> for C4Element {
fn from(p: Person) -> Self {
C4Element::Person(p)
}
}
impl From<SoftwareSystem> for C4Element {
fn from(s: SoftwareSystem) -> Self {
C4Element::SoftwareSystem(s)
}
}
impl From<Container> for C4Element {
fn from(c: Container) -> Self {
C4Element::Container(c)
}
}
impl From<Component> for C4Element {
fn from(c: Component) -> Self {
C4Element::Component(c)
}
}
impl From<Relationship> for C4Element {
fn from(r: Relationship) -> Self {
C4Element::Relationship(r)
}
}