1use serde::{Deserialize, Serialize};
2
3use crate::{config::settings::Config, core::Data, modules::enums::SongInfo};
4
5pub const PROTOCOL_VERSION: u32 = 1;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct SystemInfo {
10 pub protocol_version: u32,
11 pub username: Option<String>,
12 pub hostname: Option<String>,
13 pub host: Option<String>,
14 pub os: Option<String>,
15 pub distro: Option<String>,
16 pub model: Option<String>,
17 pub kernel: Option<String>,
18 pub os_age: Option<String>,
19 pub uptime: Option<String>,
20 pub packages: Option<String>,
21 pub shell: Option<String>,
22 pub wm: Option<String>,
23 pub de: Option<String>,
24 pub cpu: Option<String>,
25 pub gpu: Option<Vec<String>>,
26 pub memory: Option<String>,
27 pub disk: Option<Vec<(String, String)>>,
28 pub resolution: Option<String>,
29 pub theme: Option<String>,
30 pub battery: Option<Vec<String>>,
31 pub song: Option<SongInfo>,
32 pub colors: Option<String>,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct RemoteSshPayload {
38 pub config: Config,
39 pub system_info: SystemInfo,
40}
41
42impl RemoteSshPayload {
43 pub fn new(config: Config, system_info: SystemInfo) -> Self {
44 Self {
45 config,
46 system_info,
47 }
48 }
49}
50
51impl From<Data> for SystemInfo {
52 fn from(value: Data) -> Self {
53 let host = match (&value.username, &value.hostname) {
54 (Some(user), Some(host)) => Some(format!("{user}@{host}")),
55 (_, Some(host)) => Some(host.clone()),
56 _ => None,
57 };
58
59 Self {
60 protocol_version: PROTOCOL_VERSION,
61 username: value.username,
62 hostname: value.hostname,
63 host,
64 os: value.os,
65 distro: value.distro,
66 model: value.model,
67 kernel: value.kernel,
68 os_age: value.os_age,
69 uptime: value.uptime,
70 packages: value.packages,
71 shell: value.shell,
72 wm: value.wm,
73 de: value.de,
74 cpu: value.cpu,
75 gpu: value.gpu,
76 memory: value.memory,
77 disk: value.disk,
78 resolution: value.resolution,
79 theme: value.theme,
80 battery: value.battery,
81 song: value.song,
82 colors: value.colors,
83 }
84 }
85}
86
87impl From<&SystemInfo> for Data {
88 fn from(value: &SystemInfo) -> Self {
89 Data {
90 username: value.username.clone(),
91 hostname: value.hostname.clone(),
92 os: value.os.clone(),
93 distro: value.distro.clone(),
94 model: value.model.clone(),
95 kernel: value.kernel.clone(),
96 os_age: value.os_age.clone(),
97 uptime: value.uptime.clone(),
98 packages: value.packages.clone(),
99 shell: value.shell.clone(),
100 wm: value.wm.clone(),
101 de: value.de.clone(),
102 cpu: value.cpu.clone(),
103 gpu: value.gpu.clone(),
104 memory: value.memory.clone(),
105 disk: value.disk.clone(),
106 resolution: value.resolution.clone(),
107 theme: value.theme.clone(),
108 battery: value.battery.clone(),
109 song: value.song.clone(),
110 colors: value.colors.clone(),
111 }
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118 use crate::config::default_config;
119
120 fn sample_system_info() -> SystemInfo {
121 SystemInfo {
122 protocol_version: PROTOCOL_VERSION,
123 username: Some("anakin".to_string()),
124 hostname: Some("tattooine".to_string()),
125 host: Some("anakin@tattooine".to_string()),
126 os: Some("Linux".to_string()),
127 distro: Some("Arch Linux".to_string()),
128 model: Some("X1".to_string()),
129 kernel: Some("6.0.0".to_string()),
130 os_age: None,
131 uptime: None,
132 packages: None,
133 shell: None,
134 wm: None,
135 de: None,
136 cpu: None,
137 gpu: None,
138 memory: None,
139 disk: None,
140 resolution: None,
141 theme: None,
142 battery: None,
143 song: None,
144 colors: None,
145 }
146 }
147
148 #[test]
149 fn remote_ssh_payload_round_trips() {
150 let payload = RemoteSshPayload::new(default_config(), sample_system_info());
151 let encoded = serde_json::to_string(&payload).unwrap();
152 let decoded: RemoteSshPayload = serde_json::from_str(&encoded).unwrap();
153
154 assert_eq!(decoded.system_info.username.as_deref(), Some("anakin"));
155 assert_eq!(decoded.system_info.hostname.as_deref(), Some("tattooine"));
156 assert!(!decoded.config.layout.is_empty());
157 }
158}