Skip to content

Commit 3f972f1

Browse files
committed
Support serialization of machine state into files
1 parent d27eea9 commit 3f972f1

File tree

18 files changed

+268
-103
lines changed

18 files changed

+268
-103
lines changed

Cargo.lock

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,24 @@ license = "MIT"
88

99
[dependencies]
1010
clap = { version = "*", features = ["derive"] }
11-
measurements = "*"
11+
measurements = { version = "*", features = ["serde"] }
1212
nix = { version="*", features = ["feature"]}
1313
os-release = "*"
14-
procfs = "*"
14+
procfs = { version = "*", features = ["serde1"] }
1515
sys-info = "*"
1616
uptime_lib = "*"
1717
thiserror = "*"
1818
udev = "*"
1919
futures = "*"
2020
udisks2 = "*"
21+
serde = "*"
22+
serde_json = "*"
2123

2224
[build-dependencies]
2325
clap = { version = "*", features = ["derive"] }
2426
clap_complete = "*"
2527
clap_mangen = "*"
28+
serde = "*"
2629

2730
[lints.clippy]
2831
pedantic = {level="warn", priority = 0}

src/args.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::path::PathBuf;
2+
13
use crate::memunit::MemUnits;
24
use clap::Parser;
35

@@ -16,4 +18,12 @@ pub struct Args {
1618
/// Number of colour lines to show
1719
#[arg(long, default_value = "8")]
1820
pub colour_length: usize,
21+
22+
/// Import machine state
23+
#[arg(short, long)]
24+
pub input: Option<PathBuf>,
25+
26+
/// Export machine state
27+
#[arg(short, long)]
28+
pub output: Option<PathBuf>,
1929
}

src/cpu.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ use measurements::frequency::Frequency;
33
use procfs::prelude::*;
44
use procfs::CpuInfo;
55

6+
use serde::{Deserialize, Serialize};
7+
8+
#[derive(Serialize, Deserialize)]
69
pub struct Cpu {
710
cpu: CpuInfo,
811
}

src/disk.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use crate::fetcherror::FetchError;
22
use measurements::Data;
3+
use serde::{Deserialize, Serialize};
34
use std::collections::HashMap;
45

6+
#[derive(Serialize, Deserialize)]
57
pub struct Disk {
68
pub capacity: Data,
79
}

src/fetcherror.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,6 @@ pub enum FetchError {
2424
ParseInt(#[from] ParseIntError),
2525
#[error("Error talking to udisks2")]
2626
Udisk(#[from] udisks2::Error),
27+
#[error("Error with serialization")]
28+
Serde(#[from] serde_json::Error),
2729
}

src/hostname.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use sys_info::hostname;
22

33
use crate::fetcherror::FetchError;
4+
use serde::{Deserialize, Serialize};
5+
6+
#[derive(Serialize, Deserialize)]
47
pub struct HostName(pub String);
58

69
impl HostName {

src/kernel.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ use nix::sys::utsname::{uname, UtsName};
22
use std::ffi::OsStr;
33

44
use crate::fetcherror::FetchError;
5+
use serde::{Deserialize, Serialize};
56

67
type Result<T> = std::result::Result<T, FetchError>;
78

9+
#[derive(Serialize, Deserialize)]
810
pub struct Kernel {
911
release: String,
1012
architecture: String,

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pub mod fetcherror;
66
pub mod fetchsection;
77
pub mod hostname;
88
pub mod kernel;
9+
pub mod machine;
910
pub mod memory;
1011
pub mod memunit;
1112
pub mod model;

src/machine.rs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
use std::fmt::Display;
2+
use std::fs::File;
3+
use std::io::{BufReader, BufWriter, Write};
4+
use std::path::PathBuf;
5+
6+
use crate::colourblocks::colourblocks;
7+
8+
use crate::cpu::Cpu;
9+
use crate::disk::Disk;
10+
use crate::fetcherror::FetchError;
11+
use crate::fetchsection::{FetchArray, SEPARATOR};
12+
use crate::hostname::HostName;
13+
use crate::kernel::Kernel;
14+
use crate::memory::Memory;
15+
use crate::model::Model;
16+
use crate::osinfo::OsInfo;
17+
use crate::platform::Profile;
18+
use crate::shell::Shell;
19+
use crate::uptime::Uptime;
20+
21+
use serde::{Deserialize, Serialize};
22+
23+
#[derive(Serialize, Deserialize)]
24+
pub struct Machine {
25+
pub kernel: Option<Kernel>,
26+
pub cpu: Option<Cpu>,
27+
pub memory: Option<Memory>,
28+
pub os: Option<OsInfo>,
29+
pub hostname: Option<HostName>,
30+
pub uptime: Option<Uptime>,
31+
pub model: Option<Model>,
32+
pub shell: Option<Shell>,
33+
pub platform: Option<Profile>,
34+
pub disk: Option<Disk>,
35+
}
36+
37+
impl Machine {
38+
pub fn new() -> Self {
39+
Self::default()
40+
}
41+
42+
pub fn from_file(path: PathBuf) -> Result<Self, FetchError> {
43+
let f = File::open(path)?;
44+
let r = BufReader::new(f);
45+
Ok(serde_json::from_reader(r)?)
46+
}
47+
48+
pub fn to_file(&self, path: PathBuf) -> Result<(), FetchError> {
49+
let f = File::create(path)?;
50+
let mut w = BufWriter::new(f);
51+
serde_json::to_writer_pretty(&mut w, self)?;
52+
w.flush()?;
53+
Ok(())
54+
}
55+
}
56+
57+
impl Default for Machine {
58+
fn default() -> Self {
59+
Self {
60+
kernel: Kernel::new().ok(),
61+
cpu: Cpu::new().ok(),
62+
memory: Memory::new(None).ok(),
63+
os: OsInfo::new().ok(),
64+
hostname: HostName::new().ok(),
65+
uptime: Uptime::new().ok(),
66+
model: Model::new().ok(),
67+
shell: Shell::new().ok(),
68+
platform: Profile::new().ok(),
69+
disk: Disk::new().ok(),
70+
}
71+
}
72+
}
73+
74+
impl Display for Machine {
75+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76+
let mut array = FetchArray::default();
77+
78+
if let Some(r) = &self.os {
79+
array.set_colour(r.color.clone());
80+
array.push(("OS", r));
81+
}
82+
83+
if let Some(r) = &self.shell {
84+
array.push(("Shell", r));
85+
}
86+
87+
if let Some(r) = &self.kernel {
88+
array.push(("Kernel", r));
89+
}
90+
91+
if let Some(r) = &self.model {
92+
array.push(("Model", r));
93+
}
94+
95+
if let Some(r) = &self.hostname {
96+
array.push(("Hostname", r));
97+
}
98+
99+
if let Some(r) = &self.uptime {
100+
array.push(("Uptime", r));
101+
}
102+
103+
if let Some(r) = &self.cpu {
104+
array.push(("CPU", r));
105+
}
106+
107+
if let Some(r) = &self.memory {
108+
array.push(("Memory", &r));
109+
array.push(("Swap", r.display_swap()));
110+
}
111+
112+
if let Some(r) = &self.platform {
113+
array.push(("Profile", r));
114+
}
115+
116+
if let Some(r) = &self.disk {
117+
array.push(("Disk", r));
118+
}
119+
120+
write!(
121+
f,
122+
"{}\n{}",
123+
array,
124+
colourblocks(array.get_indent() + SEPARATOR.len(), 16, 8)
125+
)
126+
}
127+
}

0 commit comments

Comments
 (0)