1use serde::{Deserialize, Serialize};
2use stix_rs::{CommonProperties, StixObject};
3use crate::domain::AttackObject;
4
5#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
7pub struct Tactic {
8 #[serde(flatten)]
9 pub common: CommonProperties,
10
11 pub name: String,
12 pub description: Option<String>,
13
14 #[serde(rename = "x_mitre_shortname")]
15 pub shortname: String,
16
17 #[serde(default, rename = "x_mitre_domains")]
19 pub domains: Vec<String>,
20}
21
22impl StixObject for Tactic {
23 fn id(&self) -> &str {
24 &self.common.id
25 }
26
27 fn type_(&self) -> &str {
28 &self.common.r#type
29 }
30
31 fn created(&self) -> chrono::DateTime<chrono::Utc> {
32 self.common.created
33 }
34}
35
36impl AttackObject for Tactic {
37 fn name(&self) -> &str {
38 &self.name
39 }
40
41 fn description(&self) -> Option<&str> {
42 self.description.as_deref()
43 }
44
45 fn revoked(&self) -> bool {
46 self.common.revoked.unwrap_or(false)
47 }
48
49 fn deprecated(&self) -> bool {
50 self.common.custom_properties.get("x_mitre_deprecated").and_then(|v| v.as_bool()).unwrap_or(false)
51 }
52}