freedom_models/
task_override.rs1use std::collections::HashMap;
2
3use time::OffsetDateTime;
4use url::Url;
5
6use crate::Hateoas;
7
8#[cfg_attr(
9 feature = "serde",
10 derive(serde::Serialize, serde::Deserialize),
11 serde(rename_all = "camelCase")
12)]
13#[derive(Debug, Clone, PartialEq)]
14#[cfg_attr(not(feature = "unstable"), non_exhaustive)]
15pub struct ConfigurationDetails {
16 pub name: String,
17 pub description: String,
18}
19
20#[cfg_attr(
21 feature = "serde",
22 derive(serde::Serialize, serde::Deserialize),
23 serde(rename_all = "camelCase")
24)]
25#[derive(Debug, Clone, PartialEq)]
26#[cfg_attr(not(feature = "unstable"), non_exhaustive)]
27pub struct SatelliteDetails {
28 pub name: String,
29 pub norad: u32,
30 pub description: String,
31}
32
33#[cfg_attr(
34 feature = "serde",
35 derive(serde::Serialize, serde::Deserialize),
36 serde(rename_all = "camelCase")
37)]
38#[derive(Debug, Clone, PartialEq)]
39#[cfg_attr(not(feature = "unstable"), non_exhaustive)]
40pub struct Override {
41 #[cfg_attr(feature = "serde", serde(with = "time::serde::iso8601"))]
42 pub created: OffsetDateTime,
43 #[cfg_attr(
44 feature = "serde",
45 serde(default, with = "time::serde::iso8601::option")
46 )]
47 pub modified: Option<OffsetDateTime>,
48 #[cfg_attr(feature = "serde", serde(default))]
49 pub name: String,
50 #[cfg_attr(feature = "serde", serde(default))]
51 pub properties: HashMap<String, String>,
52 #[cfg_attr(feature = "serde", serde(alias = "satellite_details"))]
54 pub satellite_details: Option<SatelliteDetails>,
55 #[cfg_attr(feature = "serde", serde(alias = "configuration_details"))]
57 pub configuration_details: Option<ConfigurationDetails>,
58 #[cfg_attr(
59 feature = "serde",
60 serde(rename = "_links", with = "crate::utils::links::serde", default)
61 )]
62 pub links: HashMap<String, Url>,
63}
64
65impl Hateoas for Override {
66 fn get_links(&self) -> &HashMap<String, url::Url> {
67 &self.links
68 }
69
70 fn get_links_mut(&mut self) -> &mut HashMap<String, url::Url> {
71 &mut self.links
72 }
73}
74
75#[cfg(all(test, feature = "serde"))]
76mod tests {
77 use super::*;
78
79 #[test]
80 fn deserialize_override_full() {
81 let json = r#"{
82 "created": "2026-01-22T16:16:40.836788Z",
83 "modified": "2026-01-22T16:16:40.836788Z",
84 "name": "C-Test-1",
85 "properties": {
86 "my.prop": "20"
87 },
88 "satellite_details": {
89 "name": "Rustacean Nation",
90 "norad": 101,
91 "description": "this_will_work.unwrap().unwrap().unwrap()"
92 },
93 "configuration_details": {
94 "name": "MySiteConfig",
95 "description": "It's a good one!"
96 },
97 "_links": {
98 "self": {
99 "href": "http://localhost:8080/api/overrides/233"
100 },
101 "overrides": {
102 "href": "http://localhost:8080/api/overrides/233"
103 },
104 "user": {
105 "href": "http://localhost:8080/api/overrides/233/user"
106 },
107 "satellite": {
108 "href": "http://localhost:8080/api/overrides/233/satellite"
109 },
110 "configuration": {
111 "href": "http://localhost:8080/api/overrides/233/configuration"
112 }
113 }
114}"#;
115
116 let ov: Override = serde_json::from_str(json).unwrap();
117 assert_eq!(ov.satellite_details.unwrap().name, "Rustacean Nation");
118 assert_eq!(ov.configuration_details.unwrap().name, "MySiteConfig");
119 }
120
121 #[test]
122 fn deserialize_override_minimal() {
123 let json = r#"{
124 "created": "2026-01-22T16:16:40.836788Z",
125 "modified": "2026-01-22T16:16:40.836788Z",
126 "name": "C-Test-1",
127 "properties": {
128 "my.prop": "20"
129 },
130 "_links": {
131 "self": {
132 "href": "http://localhost:8080/api/overrides/233"
133 },
134 "overrides": {
135 "href": "http://localhost:8080/api/overrides/233"
136 },
137 "user": {
138 "href": "http://localhost:8080/api/overrides/233/user"
139 }
140 }
141}"#;
142
143 let ov: Override = serde_json::from_str(json).unwrap();
144 assert_eq!(ov.name, "C-Test-1");
145 assert_eq!(ov.properties.get("my.prop").unwrap(), "20");
146 }
147}