maec/objects/
capability.rs1use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6use crate::common::ExternalReference;
7use crate::error::Result;
8
9#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
13#[serde(rename_all = "snake_case")]
14pub struct Capability {
15 pub name: String,
17
18 #[serde(default, skip_serializing_if = "Vec::is_empty")]
20 pub refined_capabilities: Vec<Capability>,
21
22 #[serde(skip_serializing_if = "Option::is_none")]
24 pub description: Option<String>,
25
26 #[serde(skip_serializing_if = "Option::is_none")]
28 pub attributes: Option<HashMap<String, serde_json::Value>>,
29
30 #[serde(default, skip_serializing_if = "Vec::is_empty")]
32 pub behavior_refs: Vec<String>,
33
34 #[serde(default, skip_serializing_if = "Vec::is_empty")]
36 pub references: Vec<ExternalReference>,
37}
38
39impl Capability {
40 pub fn new(name: impl Into<String>) -> Self {
42 Self {
43 name: name.into(),
44 refined_capabilities: vec![],
45 description: None,
46 attributes: None,
47 behavior_refs: vec![],
48 references: vec![],
49 }
50 }
51
52 pub fn builder() -> CapabilityBuilder {
54 CapabilityBuilder::default()
55 }
56}
57
58#[derive(Debug, Default)]
60pub struct CapabilityBuilder {
61 name: Option<String>,
62 refined_capabilities: Vec<Capability>,
63 description: Option<String>,
64 attributes: Option<HashMap<String, serde_json::Value>>,
65 behavior_refs: Vec<String>,
66 references: Vec<ExternalReference>,
67}
68
69impl CapabilityBuilder {
70 pub fn name(mut self, name: impl Into<String>) -> Self {
71 self.name = Some(name.into());
72 self
73 }
74
75 pub fn description(mut self, desc: impl Into<String>) -> Self {
76 self.description = Some(desc.into());
77 self
78 }
79
80 pub fn add_refined_capability(mut self, capability: Capability) -> Self {
81 self.refined_capabilities.push(capability);
82 self
83 }
84
85 pub fn add_behavior_ref(mut self, ref_id: impl Into<String>) -> Self {
86 self.behavior_refs.push(ref_id.into());
87 self
88 }
89
90 pub fn add_reference(mut self, reference: ExternalReference) -> Self {
91 self.references.push(reference);
92 self
93 }
94
95 pub fn build(self) -> Result<Capability> {
96 let name = self
97 .name
98 .ok_or(crate::error::MaecError::MissingField("name"))?;
99
100 Ok(Capability {
101 name,
102 refined_capabilities: self.refined_capabilities,
103 description: self.description,
104 attributes: self.attributes,
105 behavior_refs: self.behavior_refs,
106 references: self.references,
107 })
108 }
109}