Skip to main content

attack/domain/
tactic.rs

1use serde::{Deserialize, Serialize};
2use stix_rs::{CommonProperties, StixObject};
3use crate::domain::AttackObject;
4
5/// Represents a MITRE ATT&CK Tactic (x-mitre-tactic).
6#[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    // Extended ATT&CK fields
18    #[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}