sysinfo_web/
sysinfo_serde.rs

1//! Serde serialization support for sysinfo
2//!
3//! Usage example with `serde_derive`:
4//!
5//! ```rust
6//! # #[macro_use]
7//! # extern crate serde_derive;
8//! # extern crate serde_json;
9//! # extern crate sysinfo;
10//! # extern crate sysinfo_web;
11//! # use sysinfo_web::sysinfo_serde;
12//! # use sysinfo::SystemExt;
13//! # fn main() {
14//! #[derive(Serialize)]
15//! struct Info (
16//!     #[serde(serialize_with = "sysinfo_serde::serialize")]
17//!     sysinfo::System
18//! );
19//!
20//! let mut system = sysinfo::System::new();
21//! system.refresh_all();
22//!
23//! let info = Info(system);
24//! let serialized = serde_json::to_string(&info).unwrap();
25//! # }
26//!
27//! ```
28
29
30use std::collections::HashMap;
31use serde::{Serialize, Serializer};
32use serde::ser::SerializeMap;
33use sysinfo::{System, SystemExt, Processor, ProcessorExt, Process, ProcessExt,
34              Component, ComponentExt, Disk, DiskExt, DiskType};
35
36
37pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
38    where S: Serializer,
39          for<'a> Ser<'a, T>: Serialize
40{
41    Ser::new(value).serialize(serializer)
42}
43
44
45/// A wrapper to serialize `sysinfo` types.
46pub struct Ser<'a, T: 'a>(&'a T);
47
48
49impl<'a, T> Ser<'a, T>
50    where Ser<'a, T>: Serialize
51{
52    #[inline(always)]
53    pub fn new(value: &'a T) -> Self {
54        Ser(value)
55    }
56}
57
58
59impl<'a> Serialize for Ser<'a, Processor> {
60    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
61        where S: Serializer
62    {
63        let mut map = serializer.serialize_map(None)?;
64        map.serialize_entry("name", self.0.get_name())?;
65        map.serialize_entry("cpu_usage", &self.0.get_cpu_usage())?;
66        map.end()
67    }
68}
69
70
71impl<'a> Serialize for Ser<'a, Process> {
72    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
73        where S: Serializer
74    {
75        // Do not serialize command line arguments and environment variables
76        // for extra security and save up some bandwith on each request.
77        //
78        // This is actually breaking whole idea behind this serde serializer,
79        // but since only sysinfo-web is using this serializer it should be fine.
80        let mut map = serializer.serialize_map(None)?;
81        map.serialize_entry("name", &self.0.name())?;
82        //map.serialize_entry("cmd", &self.0.cmd())?;
83        map.serialize_entry("exe", &self.0.exe())?;
84        map.serialize_entry("pid", &self.0.pid())?;
85        map.serialize_entry("parent", &self.0.parent())?;
86        //map.serialize_entry("environ", &self.0.environ())?;
87        map.serialize_entry("cwd", &self.0.cwd())?;
88        map.serialize_entry("root", &self.0.root())?;
89        map.serialize_entry("memory", &self.0.memory())?;
90        map.serialize_entry("start_time", &self.0.start_time())?;
91        map.serialize_entry("cpu_usage", &self.0.cpu_usage())?;
92        map.serialize_entry("uid", &self.0.uid)?;
93        map.serialize_entry("gid", &self.0.gid)?;
94        #[cfg(target_os = "linux")]
95        map.serialize_entry("tasks", &Ser::new(&self.0.tasks))?;
96        map.end()
97    }
98}
99
100
101impl<'a> Serialize for Ser<'a, HashMap<i32, Process>> {
102    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
103        where S: Serializer
104    {
105        let mut map = serializer.serialize_map(None)?;
106        for (pid, process) in self.0.iter() {
107            map.serialize_key(pid)?;
108            map.serialize_value(&Ser::new(process))?;
109        }
110        map.end()
111    }
112}
113
114
115impl<'a> Serialize for Ser<'a, Component> {
116    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
117        where S: Serializer
118    {
119        let mut map = serializer.serialize_map(None)?;
120        map.serialize_entry("temperature", &self.0.get_temperature())?;
121        map.serialize_entry("max", &self.0.get_max())?;
122        map.serialize_entry("critical", &self.0.get_critical())?;
123        map.serialize_entry("label", &self.0.get_label())?;
124        map.end()
125    }
126}
127
128
129impl<'a> Serialize for Ser<'a, Disk> {
130    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
131        where S: Serializer
132    {
133        let mut map = serializer.serialize_map(None)?;
134        map.serialize_entry("type",
135                             &match self.0.get_type() {
136                                 DiskType::HDD => "HDD".to_owned(),
137                                 DiskType::SSD => "SSD".to_owned(),
138                                 DiskType::Unknown(size) => format!("Unknown({})", size),
139                             })?;
140        map.serialize_entry("name", self.0.get_name().to_str().unwrap())?;
141        map.serialize_entry("file_system", ::std::str::from_utf8(self.0.get_file_system()).unwrap())?;
142        map.serialize_entry("mount_point", self.0.get_mount_point())?;
143        map.serialize_entry("total_space", &self.0.get_total_space())?;
144        map.serialize_entry("available_space", &self.0.get_available_space())?;
145        map.end()
146    }
147}
148
149
150impl<'a> Serialize for Ser<'a, System> {
151    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
152        where S: Serializer
153    {
154        let mut map = serializer.serialize_map(None)?;
155        map.serialize_entry("process_list", &Ser::new(self.0.get_process_list()))?;
156        map.serialize_entry("processor_list",
157                             &self.0
158                                 .get_processor_list()
159                                 .iter()
160                                 .map(|p| Ser::new(p))
161                                 .collect::<Vec<Ser<Processor>>>())?;
162        map.serialize_entry("total_memory", &self.0.get_total_memory())?;
163        map.serialize_entry("free_memory", &self.0.get_free_memory())?;
164        map.serialize_entry("used_memory", &self.0.get_used_memory())?;
165        map.serialize_entry("total_swap", &self.0.get_total_swap())?;
166        map.serialize_entry("free_swap", &self.0.get_free_swap())?;
167        map.serialize_entry("used_swap", &self.0.get_used_swap())?;
168        map.serialize_entry("components_list",
169                             &self.0
170                                 .get_components_list()
171                                 .iter()
172                                 .map(|c| Ser::new(c))
173                                 .collect::<Vec<Ser<Component>>>())?;
174        map.serialize_entry("disks",
175                             &self.0
176                                 .get_disks()
177                                 .iter()
178                                 .map(|c| Ser::new(c))
179                                 .collect::<Vec<Ser<Disk>>>())?;
180
181        map.end()
182    }
183}