sysutil/
lib.rs

1//! Linux system information library
2//!
3//! <div class="warning">This library is ment to be used only in linux systems. It is possible to write code using it on other systems, but it will not allow to run the code, panicking before execution </div>
4//!
5//! # Installation
6//!
7//! Run the following command in your terminal
8//!
9//! ```bash
10//! cargo add sysutil
11//! ```
12//!
13//! # Importation
14//! Add in your code:
15//! ```
16//! use sysutil;
17//! ```
18//!
19//! ---
20//! <div class="warning">GPU's related functions have been tested only on AMD Radeon 7000 series, any other GPU model is not "officially supported"</div>
21
22#![allow(non_snake_case)]
23#![allow(dead_code)]
24#![allow(non_camel_case_types)]
25
26pub mod gpu;
27pub mod cpu;
28pub mod ram;
29pub mod network;
30pub mod storage;
31pub mod motherboard;
32pub mod sensors;
33pub mod bus;
34mod utils;
35pub use utils::{ByteSize, ByteUnit};
36
37use rsjson::{Json, Node, NodeContent};
38
39/// Returns a `rsjson::Json` object containing all the data which `sysutil` can extract
40pub fn exportJson() -> rsjson::Json {
41    let mut json = rsjson::Json::new();
42
43    let mut cpuNodeContent = rsjson::Json::new();
44    let cpu = cpu::CPU::new();
45
46    cpuNodeContent.addNode(rsjson::Node::new(
47        "model-name".to_string(),
48        NodeContent::String(cpu.info.modelName)
49    ));
50
51    cpuNodeContent.addNode(rsjson::Node::new(
52        "cores".to_string(),
53        NodeContent::Int(cpu.info.cores)
54    ));
55
56    cpuNodeContent.addNode(rsjson::Node::new(
57        "threads".to_string(),
58        NodeContent::Int(cpu.info.threads)
59    ));
60
61    cpuNodeContent.addNode(rsjson::Node::new(
62        "dies".to_string(),
63        NodeContent::Int(cpu.info.dies)
64    ));
65
66    cpuNodeContent.addNode(rsjson::Node::new(
67        "governors".to_string(),
68        NodeContent::List(Vec::<NodeContent>::from({
69            let mut list = Vec::<NodeContent>::new();
70
71            for governor in cpu.info.governors {
72                list.push(NodeContent::String(governor));
73            }
74
75            list
76        }))
77    ));
78
79    cpuNodeContent.addNode(rsjson::Node::new(
80        "max-frequency".to_string(),
81        NodeContent::Float(cpu.info.maxFrequencyMHz)
82    ));
83
84    cpuNodeContent.addNode(rsjson::Node::new(
85        "clock-boost".to_string(),
86        {
87            if cpu.info.clockBoost == None {
88                NodeContent::Null
89            } else {
90                NodeContent::Bool(cpu.info.clockBoost.unwrap())
91            }
92        }
93    ));
94
95    cpuNodeContent.addNode(rsjson::Node::new(
96        "architecture".to_string(),
97        NodeContent::String(cpu.info.architecture)
98    ));
99
100    cpuNodeContent.addNode(rsjson::Node::new(
101        "byte-order".to_string(),
102        NodeContent::String(cpu.info.byteOrder)
103    ));
104
105    let mut cpuAverageUsageNodeContent = Json::new();
106    cpuAverageUsageNodeContent.addNode(Node::new(
107        "total".to_string(),
108        NodeContent::Float(cpu.averageUsage.total)
109    ));
110
111    cpuAverageUsageNodeContent.addNode(Node::new(
112        "user".to_string(),
113        NodeContent::Float(cpu.averageUsage.user)
114    ));
115
116    cpuAverageUsageNodeContent.addNode(Node::new(
117        "nice".to_string(),
118        NodeContent::Float(cpu.averageUsage.nice)
119    ));
120
121    cpuAverageUsageNodeContent.addNode(Node::new(
122        "system".to_string(),
123        NodeContent::Float(cpu.averageUsage.system)
124    ));
125
126    cpuAverageUsageNodeContent.addNode(Node::new(
127        "idle".to_string(),
128        NodeContent::Float(cpu.averageUsage.idle)
129    ));
130
131    cpuAverageUsageNodeContent.addNode(Node::new(
132        "iowait".to_string(),
133        NodeContent::Float(cpu.averageUsage.iowait)
134    ));
135
136    cpuAverageUsageNodeContent.addNode(Node::new(
137        "interrupt".to_string(),
138        NodeContent::Float(cpu.averageUsage.interrupt)
139    ));
140
141    cpuAverageUsageNodeContent.addNode(Node::new(
142        "soft-interrupt".to_string(),
143        NodeContent::Float(cpu.averageUsage.soft_interrupt)
144    ));
145
146    let mut cpuSchedulerPolicyContent = Json::new();
147
148    for policy in cpu.schedulerPolicies {
149        let mut policyNodeContent = Json::new();
150
151        policyNodeContent.addNode(Node::new(
152            "scaling-governor".to_string(),
153            NodeContent::String(policy.scalingGovernor)
154        ));
155
156        policyNodeContent.addNode(Node::new(
157            "scaling-driver".to_string(),
158            NodeContent::String(policy.scalingDriver)
159        ));
160
161        policyNodeContent.addNode(Node::new(
162            "minimum-scaling-mhz".to_string(),
163            NodeContent::Float(policy.minimumScalingMHz)
164        ));
165
166        policyNodeContent.addNode(Node::new(
167            "maximum-scaling-mhz".to_string(),
168            NodeContent::Float(policy.maximumScalingMHz)
169        ));
170
171        cpuSchedulerPolicyContent.addNode(Node::new(
172            policy.name.to_string(),
173            NodeContent::Json(policyNodeContent)
174        ));
175    }
176
177    cpuNodeContent.addNode(Node::new(
178        "usage".to_string(),
179        NodeContent::Json(cpuAverageUsageNodeContent)
180    ));
181
182    cpuNodeContent.addNode(Node::new(
183        "scheduler-policies".to_string(),
184        NodeContent::Json(cpuSchedulerPolicyContent)
185    ));
186
187    cpuNodeContent.addNode(Node::new(
188        "frequency".to_string(),
189        NodeContent::Int(cpu.averageFrequency.khz)
190    ));
191
192    let mut cpuClockSourceNodeContent = Json::new();
193    let clockSource = cpu::clockSource();
194
195    cpuClockSourceNodeContent.addNode(Node::new(
196        "current".to_string(),
197        NodeContent::String(clockSource.current)
198    ));
199
200    cpuClockSourceNodeContent.addNode(Node::new(
201        "available".to_string(),
202        NodeContent::List({
203            let mut list = Vec::<NodeContent>::new();
204
205            for source in clockSource.available {
206                list.push(NodeContent::String(source));
207            }
208
209            list
210        })
211    ));
212
213    cpuNodeContent.addNode(Node::new(
214        "clock-source".to_string(),
215        NodeContent::Json(cpuClockSourceNodeContent)
216    ));
217
218    json.addNode(rsjson::Node::new(
219        "cpu".to_string(),
220        NodeContent::Json(cpuNodeContent)
221    ));
222
223    let mut ramNodeContent = Json::new();
224    let ram = ram::RAM::new();
225
226    ramNodeContent.addNode(Node::new(
227        "usage".to_string(),
228        NodeContent::Float(ram.usage)
229    ));
230
231    ramNodeContent.addNode(Node::new(
232        "size-gib".to_string(),
233        NodeContent::Float(ram.size.GiB())
234    ));
235
236    ramNodeContent.addNode(Node::new(
237        "frequency",
238        match ram.frequency {
239            Some(frequency) => {
240                NodeContent::Int(frequency)
241            },
242            None => NodeContent::Null
243        }
244    ));
245
246    ramNodeContent.addNode(Node::new(
247        "width",
248        match ram.busWidth {
249            Some(width) => {
250                NodeContent::Int(width)
251            },
252            None => NodeContent::Null
253        }
254    ));
255
256    json.addNode(Node::new(
257        "ram".to_string(),
258        NodeContent::Json(ramNodeContent)
259    ));
260
261    let mut motherBoardNodeContent = Json::new();
262    let motherboard = motherboard::motherboardInfo();
263
264    motherBoardNodeContent.addNode(Node::new(
265        "name".to_string(),
266        NodeContent::String(motherboard.name)
267    ));
268
269    motherBoardNodeContent.addNode(Node::new(
270        "vendor".to_string(),
271        NodeContent::String(motherboard.vendor)
272    ));
273
274    motherBoardNodeContent.addNode(Node::new(
275        "version".to_string(),
276        NodeContent::String(motherboard.version)
277    ));
278
279    let mut biosNodeContent = Json::new();
280    biosNodeContent.addNode(Node::new(
281        "vendor".to_string(),
282        NodeContent::String(motherboard.bios.vendor)
283    ));
284
285    biosNodeContent.addNode(Node::new(
286        "release".to_string(),
287        NodeContent::String(motherboard.bios.release)
288    ));
289
290    biosNodeContent.addNode(Node::new(
291        "version".to_string(),
292        NodeContent::String(motherboard.bios.version)
293    ));
294
295    biosNodeContent.addNode(Node::new(
296        "date".to_string(),
297        NodeContent::String(motherboard.bios.date)
298    ));
299
300    motherBoardNodeContent.addNode(Node::new(
301        "bios".to_string(),
302        NodeContent::Json(biosNodeContent)
303    ));
304
305    json.addNode(Node::new(
306        "motherboard".to_string(),
307        NodeContent::Json(motherBoardNodeContent)
308    ));
309
310    let mut nvmeDevicesNodeContent = Vec::<NodeContent>::new();
311    let nvmeDevices = storage::nvmeDevices();
312
313    for device in nvmeDevices {
314        let mut deviceNodeContent = Json::new();
315
316        deviceNodeContent.addNode(Node::new(
317            "device".to_string(),
318            NodeContent::String(device.device)
319        ));
320
321        deviceNodeContent.addNode(Node::new(
322            "pcie-address".to_string(),
323            NodeContent::String(device.pcieAddress)
324        ));
325
326        deviceNodeContent.addNode(Node::new(
327            "model".to_string(),
328            NodeContent::String(device.model)
329        ));
330
331        deviceNodeContent.addNode(Node::new(
332            "link-speed-gts".to_string(),
333            NodeContent::Float(device.linkSpeedGTs)
334        ));
335
336        deviceNodeContent.addNode(Node::new(
337            "pcie-lanes".to_string(),
338            NodeContent::Int(device.pcieLanes)
339        ));
340
341        deviceNodeContent.addNode(Node::new(
342            "size".to_string(),
343            NodeContent::Int(device.size.b())
344        ));
345
346        let mut partitionsNodeList = Vec::<NodeContent>::new();
347        for partition in device.partitions {
348            let mut partitionNodeContent = Json::new();
349
350            partitionNodeContent.addNode(Node::new(
351                "device".to_string(),
352                NodeContent::String(partition.device)
353            ));
354
355            partitionNodeContent.addNode(Node::new(
356                "mount-point".to_string(),
357                NodeContent::String(partition.mountPoint)
358            ));
359
360            partitionNodeContent.addNode(Node::new(
361                "filesystem".to_string(),
362                NodeContent::String(partition.fileSystem)
363            ));
364
365            partitionNodeContent.addNode(Node::new(
366                "size".to_string(),
367                NodeContent::Int(partition.size.b())
368            ));
369
370            partitionNodeContent.addNode(Node::new(
371                "start-point".to_string(),
372                NodeContent::Int(partition.startPoint)
373            ));
374
375            partitionsNodeList.push(NodeContent::Json(partitionNodeContent));
376        }
377
378        deviceNodeContent.addNode(Node::new(
379            "partitions".to_string(),
380            NodeContent::List(partitionsNodeList)
381        ));
382
383        nvmeDevicesNodeContent.push(NodeContent::Json(deviceNodeContent));
384    }
385
386    json.addNode(Node::new(
387        "nvme-devices".to_string(),
388        NodeContent::List(nvmeDevicesNodeContent)
389    ));
390
391    let mut storageDevicesNodeContent = Vec::<NodeContent>::new();
392    let storageDevices = storage::storageDevices();
393
394    for device in storageDevices {
395        let mut deviceNodeContent = Json::new();
396
397        deviceNodeContent.addNode(Node::new(
398            "device".to_string(),
399            NodeContent::String(device.device)
400        ));
401
402        deviceNodeContent.addNode(Node::new(
403            "model".to_string(),
404            NodeContent::String(device.model)
405        ));
406
407
408        deviceNodeContent.addNode(Node::new(
409            "size".to_string(),
410            NodeContent::Int(device.size.b())
411        ));
412
413        let mut partitionsNodeList = Vec::<NodeContent>::new();
414        for partition in device.partitions {
415            let mut partitionNodeContent = Json::new();
416
417            partitionNodeContent.addNode(Node::new(
418                "device".to_string(),
419                NodeContent::String(partition.device)
420            ));
421
422            partitionNodeContent.addNode(Node::new(
423                "mount-point".to_string(),
424                NodeContent::String(partition.mountPoint)
425            ));
426
427            partitionNodeContent.addNode(Node::new(
428                "filesystem".to_string(),
429                NodeContent::String(partition.fileSystem)
430            ));
431
432            partitionNodeContent.addNode(Node::new(
433                "size".to_string(),
434                NodeContent::Int(partition.size.b())
435            ));
436
437            partitionNodeContent.addNode(Node::new(
438                "start-point".to_string(),
439                NodeContent::Int(partition.startPoint)
440            ));
441
442            partitionsNodeList.push(NodeContent::Json(partitionNodeContent));
443        }
444
445        deviceNodeContent.addNode(Node::new(
446            "partitions".to_string(),
447            NodeContent::List(partitionsNodeList)
448        ));
449
450        storageDevicesNodeContent.push(NodeContent::Json(deviceNodeContent));
451    }
452
453    json.addNode(Node::new(
454        "storage-devices".to_string(),
455        NodeContent::List(storageDevicesNodeContent)
456    ));
457
458    match sensors::batteryInfo() {
459        None => {
460            json.addNode(Node::new(String::from("battery"), NodeContent::Null));
461        },
462        Some(battery) => {
463            let mut batteryNodeContent = Json::new();
464
465            batteryNodeContent.addNode(Node::new(
466                String::from("capacity"),
467                NodeContent::Int(battery.capacity as usize)
468            ));
469
470            batteryNodeContent.addNode(Node::new(
471                String::from("status"),
472                match battery.status {
473                    sensors::BatteryStatus::Charging => NodeContent::String(String::from("Charging")),
474                    sensors::BatteryStatus::Discharging => NodeContent::String(String::from("Discharging")),
475                    sensors::BatteryStatus::Full => NodeContent::String(String::from("Full")),
476                }
477            ));
478
479            json.addNode(Node::new(
480                String::from("battery"),
481                NodeContent::Json(batteryNodeContent)
482            ));
483        }
484    };
485
486    match sensors::getBacklight() {
487        None => {
488            json.addNode(Node::new(String::from("backlight"), NodeContent::Null));
489        },
490        Some(backlight) => {
491            let mut brightnessNodeContent = Json::new();
492
493            brightnessNodeContent.addNode(Node::new(
494                String::from("brightness"),
495                NodeContent::Int(backlight.brightness as usize)
496            ));
497
498            brightnessNodeContent.addNode(Node::new(
499                String::from("max-brightness"),
500                NodeContent::Int(backlight.maxBrightness as usize)
501            ));
502
503            json.addNode(Node::new(
504                String::from("backlight"),
505                NodeContent::Json(brightnessNodeContent)
506            ));
507        }
508    }
509
510    let mut networkNodeContent = rsjson::Json::new();
511    let mut networkRateNodeContent = rsjson::Json::new();
512
513    let networkRate = network::networkRate();
514
515    networkRateNodeContent.addNode(Node::new(
516        "download",
517        NodeContent::Float(networkRate.download)
518    ));
519
520    networkRateNodeContent.addNode(Node::new(
521        "upload",
522        NodeContent::Float(networkRate.upload)
523    ));
524
525    networkNodeContent.addNode(Node::new(
526        "rate",
527        NodeContent::Json(networkRateNodeContent)
528    ));
529
530    let mut networkRoutesNodeConent = Vec::<NodeContent>::new();
531    let routes = network::networkRoutes();
532
533    for route in routes {
534        let mut routeNodeContent = rsjson::Json::new();
535
536        routeNodeContent.addNode(Node::new(
537            "type",
538            NodeContent::String(match route.routeType {
539                network::RouteType::TCP => String::from("TCP"),
540                network::RouteType::TCP6 => String::from("TCP6"),
541                network::RouteType::UDP => String::from("UDP"),
542                network::RouteType::UDP6 => String::from("UDP6")
543            })
544        ));
545
546        routeNodeContent.addNode(Node::new(
547            "local-address",
548            NodeContent::String(route.localAddress)
549        ));
550
551        routeNodeContent.addNode(Node::new(
552            "local-port",
553            NodeContent::Int(route.localPort as usize)
554        ));
555
556        routeNodeContent.addNode(Node::new(
557            "remote-address",
558            NodeContent::String(route.remoteAddress)
559        ));
560
561        routeNodeContent.addNode(Node::new(
562            "remote-port",
563            NodeContent::Int(route.remotePort as usize)
564        ));
565
566        routeNodeContent.addNode(Node::new(
567            "route-status",
568            NodeContent::String(route.routeStatus.toString())
569        ));
570
571        networkRoutesNodeConent.push(NodeContent::Json(routeNodeContent));
572    }
573
574    networkNodeContent.addNode(Node::new(
575        "routes",
576        NodeContent::List(networkRoutesNodeConent)
577    ));
578
579    json.addNode(Node::new(
580        "network",
581        NodeContent::Json(networkNodeContent)
582    ));
583
584    let temperatureSensors = sensors::temperatureSensors();
585    let mut temperatureSensorsNodeContent = Vec::<NodeContent>::new();
586
587    for sensor in temperatureSensors {
588        let mut temperatureSensorNodeContent = Json::new();
589
590        temperatureSensorNodeContent.addNode(Node::new(
591            "label",
592            NodeContent::String(sensor.label)
593        ));
594
595        temperatureSensorNodeContent.addNode(Node::new(
596            "temperature",
597            match sensor.temperature {
598                None => NodeContent::Null,
599                Some(temp) => NodeContent::Float(temp)
600            }
601        ));
602
603        temperatureSensorsNodeContent.push(NodeContent::Json(temperatureSensorNodeContent));
604    }
605
606    json.addNode(Node::new(
607        "temperature-sensors",
608        NodeContent::List(temperatureSensorsNodeContent)
609    ));
610
611    let mut vramNodeContent = Json::new();
612    let vram = gpu::VRAM::new();
613
614    vramNodeContent.addNode(Node::new(
615        "size-gib",
616        match vram.size {
617            Some(size) => {
618                NodeContent::Float(size.GiB())
619            },
620
621            None => {
622                NodeContent::Null
623            }
624        }
625    ));
626
627    vramNodeContent.addNode(Node::new(
628        "usage",
629        match vram.usage {
630            Some(usage) => {
631                NodeContent::Float(usage)
632            },
633
634            None => {
635                NodeContent::Null
636            }
637        }
638    ));
639
640    vramNodeContent.addNode(Node::new(
641        "frequency",
642        match vram.frequency {
643            Some(frequency) => {
644                NodeContent::Int(frequency)
645            },
646
647            None => {
648                NodeContent::Null
649            }
650        }
651    ));
652
653    vramNodeContent.addNode(Node::new(
654        "bus-width",
655        match vram.busWidth {
656            Some(width) => {
657                NodeContent::Int(width)
658            },
659
660            None => {
661                NodeContent::Null
662            }
663        }
664    ));
665
666    json.addNode(Node::new(
667        "vram",
668        NodeContent::Json(vramNodeContent)
669    ));
670
671    match gpu::gpuMetrics() {
672        None => {
673            json.addNode(Node::new(
674                "gpu-metrics",
675                NodeContent::Null
676            ));
677        },
678        Some(metrics) => {
679            let mut metricsNodeContent = Json::new();
680
681            metricsNodeContent.addNode(Node::new(
682                "temperature-edge",
683                NodeContent::Int(metrics.temperatureEdge as usize)
684            ));
685
686            metricsNodeContent.addNode(Node::new(
687                "temperature-hotspot",
688                NodeContent::Int(metrics.temperatureHotspot as usize)
689            ));
690
691            metricsNodeContent.addNode(Node::new(
692                "temperature-mem",
693                NodeContent::Int(metrics.temperatureMem as usize)
694            ));
695
696            metricsNodeContent.addNode(Node::new(
697                "temperature-vrgfx",
698                NodeContent::Int(metrics.temperatureVrgfx as usize)
699            ));
700
701            metricsNodeContent.addNode(Node::new(
702                "temperature-vrsoc",
703                NodeContent::Int(metrics.temperatureVrsoc as usize)
704            ));
705
706            metricsNodeContent.addNode(Node::new(
707                "temperature-vrmem",
708                NodeContent::Int(metrics.temperatureVrmem as usize)
709            ));
710
711            metricsNodeContent.addNode(Node::new(
712                "average-socket-power",
713                NodeContent::Int(metrics.averageSocketPower as usize)
714            ));
715
716            metricsNodeContent.addNode(Node::new(
717                "average-gfxclk-frequency",
718                NodeContent::Int(metrics.averageGfxclkFrequency as usize)
719            ));
720
721            metricsNodeContent.addNode(Node::new(
722                "average-sockclk-frequency",
723                NodeContent::Int(metrics.averageSockclkFrequency as usize)
724            ));
725
726            metricsNodeContent.addNode(Node::new(
727                "average-uclk-frequency",
728                NodeContent::Int(metrics.averageUclkFrequency as usize)
729            ));
730
731            metricsNodeContent.addNode(Node::new(
732                "current-gfxclk",
733                NodeContent::Int(metrics.currentGfxclk as usize)
734            ));
735
736            metricsNodeContent.addNode(Node::new(
737                "current-sockclk",
738                NodeContent::Int(metrics.currentSockclk as usize)
739            ));
740
741            metricsNodeContent.addNode(Node::new(
742                "throttle-status",
743                NodeContent::Int(metrics.throttleStatus as usize),
744            ));
745
746            metricsNodeContent.addNode(Node::new(
747                "current-fan-speed",
748                NodeContent::Int(metrics.currentFanSpeed as usize),
749            ));
750
751            metricsNodeContent.addNode(Node::new(
752                "pcie-link-width",
753                NodeContent::Int(metrics.pcieLinkWidth as usize),
754            ));
755
756            metricsNodeContent.addNode(Node::new(
757                "pcie-link-speed",
758                NodeContent::Int(metrics.pcieLinkSpeed as usize),
759            ));
760
761            json.addNode(Node::new(
762                "gpu-metrics",
763                NodeContent::Json(metricsNodeContent)
764            ));
765        }
766    }
767
768    let load = cpu::getLoad();
769
770    let mut loadNodeContent = Json::new();
771    loadNodeContent.addNode(Node::new(
772        "one-minute", NodeContent::Float(load.oneMinute)
773    ));
774
775    loadNodeContent.addNode(Node::new(
776        "five-minutes", NodeContent::Float(load.fiveMinutes)
777    ));
778
779    loadNodeContent.addNode(Node::new(
780        "fifteen-minutes", NodeContent::Float(load.fifteenMinutes)
781    ));
782
783    json.addNode(Node::new(
784        "load", NodeContent::Json(loadNodeContent)
785    ));
786
787    let mut ipv4NodeContent = Vec::<NodeContent>::new();
788    for ipv4 in network::getIPv4() {
789        let mut ipNode = rsjson::Json::new();
790
791        ipNode.addNode(Node::new(
792            "address",
793            NodeContent::String(ipv4.address)
794        ));
795
796        ipNode.addNode(Node::new(
797            "interface",
798            NodeContent::String(ipv4.interface)
799        ));
800
801        ipv4NodeContent.push(NodeContent::Json(ipNode));
802    }
803
804    json.addNode(Node::new(
805        "ipv4",
806        NodeContent::List(ipv4NodeContent)
807    ));
808
809    let mut busInputNodeContent = Vec::<NodeContent>::new();
810    for input in bus::busInput() {
811        let mut inputNode = rsjson::Json::new();
812
813        inputNode.addNode(Node::new(
814            "bus",
815            NodeContent::Int(input.bus as usize)
816        ));
817
818        inputNode.addNode(Node::new(
819            "vendor",
820            NodeContent::Int(input.vendor as usize)
821        ));
822
823        inputNode.addNode(Node::new(
824            "product",
825            NodeContent::Int(input.product as usize)
826        ));
827
828        inputNode.addNode(Node::new(
829            "version",
830            NodeContent::Int(input.version as usize)
831        ));
832
833        inputNode.addNode(Node::new(
834            "physical-path",
835            NodeContent::String(input.physicalPath)
836        ));
837
838        inputNode.addNode(Node::new(
839            "sysfs-path",
840            NodeContent::String(input.sysfsPath)
841        ));
842
843        inputNode.addNode(Node::new(
844            "name",
845            NodeContent::String(input.name)
846        ));
847
848        inputNode.addNode(Node::new(
849            "handles",
850            NodeContent::List({
851                let mut binding = Vec::<NodeContent>::new();
852
853                for handle in input.handles {
854                    binding.push(NodeContent::String(handle));
855                }
856
857                binding
858            })
859        ));
860
861        inputNode.addNode(Node::new(
862            "properties",
863            NodeContent::Int(input.properties as usize)
864        ));
865
866        inputNode.addNode(Node::new(
867            "events",
868            NodeContent::Int(input.events as usize)
869        ));
870
871        inputNode.addNode(Node::new(
872            "keys",
873            NodeContent::List({
874                let mut binding = Vec::<NodeContent>::new();
875
876                for key in input.keys {
877                    binding.push(NodeContent::String(key));
878                }
879
880                binding
881            })
882        ));
883
884        inputNode.addNode(Node::new(
885            "miscellaneous-events",
886            NodeContent::Int(input.miscellaneousEvents as usize)
887        ));
888
889        inputNode.addNode(Node::new(
890            "led",
891            NodeContent::Int(input.led as usize)
892        ));
893
894        busInputNodeContent.push(NodeContent::Json(inputNode));
895    }
896
897    json.addNode(Node::new(
898        "bus-input",
899        NodeContent::List(busInputNodeContent)
900    ));
901
902    let netIfaces = network::networkInterfaces();
903    let mut ifacesNodeContent = rsjson::Json::new();
904
905    for iface in netIfaces {
906        let mut ifaceNodeContent = rsjson::Json::new();
907
908        ifaceNodeContent.addNode(Node::new(
909            "mac",
910            NodeContent::String(iface.macAddress)
911        ));
912
913        ifaceNodeContent.addNode(Node::new(
914            "interface-type",
915            NodeContent::String(match iface.interfaceType {
916                network::InterfaceType::Physical => String::from("physical"),
917                network::InterfaceType::Virtual => String::from("virtual")
918            })
919        ));
920
921        ifacesNodeContent.addNode(Node::new(
922            iface.name,
923            NodeContent::Json(ifaceNodeContent)
924        ));
925    }
926
927    json.addNode(Node::new(
928        "network-interfaces",
929        NodeContent::Json(ifacesNodeContent)
930    ));
931
932    return json
933}
934
935#[cfg(test)]
936mod tests {
937    use super::*;
938
939    #[test]
940    fn test() {
941        // println!("{:?}", storage::nvmeDevices());
942
943        /*println!("{:?}", cpuUsage());
944        println!("RAM usage: {:?}", ramUsage());
945
946        println!("{:?}", networkRate().download / 1024_f32 / 1024_f32);
947        println!("GPU usage: {:?}", gpuUsage());
948
949        println!("{:?}", temperatureSensors());
950        println!("{:?}", cpuInfo());
951
952        println!("{:?}", ramSize());
953        println!("{:?}", schedulerInfo());
954
955        println!("{:?}", batteryInfo());
956        println!("{:?}", vramSize());
957
958        println!("VRAM usage: {:?}", vramUsage());
959        println!("{:?}", networkRoutes());
960
961        let cpu = CPU::new();
962        println!("{:?}", cpu);
963
964        println!("{:?}", cpuFrequency());
965
966        println!("{:?}", clockSource());
967        println!("{:?}", motherboardInfo());
968
969        println!("{:?}", gpuMetrics());
970        println!("{:?}", nvmeDevices());
971        println!("{:?}", storageDevices());
972
973        println!("{:?}", getBacklight());
974        println!("{:?}", getLoad());*/
975
976        //println!("{:?}", getIPv4());
977        /*println!("{:?}", busInput());*/
978
979        /*let j = exportJson();
980        j.writeToFile("file.json");*/
981
982        // for i in cpu::cacheLevels() {
983        //     let (level, size) = i;
984        //
985        //     let (size, unit) = size.fitBase1024();
986        //     println!("{level} {} {}", size, unit.toString());
987        // }
988
989        println!("{:?}", network::networkInterfaces());
990
991        assert_eq!(0_u8, 0_u8);
992    }
993}