refactored formatted scripts
Some checks failed
Build Zenyx ⚡ / 🧪 Run Cargo Tests (pull_request) Failing after 3m47s
Build Zenyx ⚡ / 🏗️ Build aarch64-apple-darwin (pull_request) Has been skipped
Build Zenyx ⚡ / 🏗️ Build aarch64-pc-windows-msvc (pull_request) Has been skipped
Build Zenyx ⚡ / 🏗️ Build aarch64-unknown-linux-gnu (pull_request) Has been skipped
Build Zenyx ⚡ / 🏗️ Build x86_64-apple-darwin (pull_request) Has been skipped
Build Zenyx ⚡ / 🏗️ Build x86_64-pc-windows-msvc (pull_request) Has been skipped
Build Zenyx ⚡ / 🏗️ Build x86_64-unknown-linux-gnu (pull_request) Has been skipped
Some checks failed
Build Zenyx ⚡ / 🧪 Run Cargo Tests (pull_request) Failing after 3m47s
Build Zenyx ⚡ / 🏗️ Build aarch64-apple-darwin (pull_request) Has been skipped
Build Zenyx ⚡ / 🏗️ Build aarch64-pc-windows-msvc (pull_request) Has been skipped
Build Zenyx ⚡ / 🏗️ Build aarch64-unknown-linux-gnu (pull_request) Has been skipped
Build Zenyx ⚡ / 🏗️ Build x86_64-apple-darwin (pull_request) Has been skipped
Build Zenyx ⚡ / 🏗️ Build x86_64-pc-windows-msvc (pull_request) Has been skipped
Build Zenyx ⚡ / 🏗️ Build x86_64-unknown-linux-gnu (pull_request) Has been skipped
cpu struct types being worked on cpu error handling fixed moved from anyhow -> thiserror other shit i'm too tired to mention
This commit is contained in:
parent
528d4b03a3
commit
f8316f8ee4
32 changed files with 568 additions and 405 deletions
77
Cargo.lock
generated
77
Cargo.lock
generated
|
@ -555,6 +555,15 @@ dependencies = [
|
|||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
|
@ -671,6 +680,28 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991"
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678"
|
||||
dependencies = [
|
||||
"derive_more-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more-impl"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "detect-desktop-environment"
|
||||
version = "1.2.0"
|
||||
|
@ -1016,9 +1047,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.2"
|
||||
version = "0.15.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
|
||||
checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
"equivalent",
|
||||
|
@ -1455,7 +1486,7 @@ dependencies = [
|
|||
"petgraph",
|
||||
"rustc-hash",
|
||||
"spirv",
|
||||
"strum",
|
||||
"strum 0.26.3",
|
||||
"thiserror 2.0.12",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
@ -2637,9 +2668,15 @@ version = "0.26.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
|
||||
dependencies = [
|
||||
"strum_macros",
|
||||
"strum_macros 0.26.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.27.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32"
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.26.4"
|
||||
|
@ -2653,6 +2690,19 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.27.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.101"
|
||||
|
@ -2710,17 +2760,20 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
|||
name = "telemetry"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ash",
|
||||
"chrono",
|
||||
"derive_more",
|
||||
"detect-desktop-environment",
|
||||
"hidapi",
|
||||
"humansize",
|
||||
"metal 0.32.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum 0.27.1",
|
||||
"strum_macros 0.27.1",
|
||||
"sys-locale",
|
||||
"sysinfo",
|
||||
"thiserror 2.0.12",
|
||||
"timeago",
|
||||
"versions",
|
||||
"wgpu",
|
||||
|
@ -2966,6 +3019,12 @@ version = "0.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
||||
|
||||
[[package]]
|
||||
name = "v_frame"
|
||||
version = "0.3.8"
|
||||
|
@ -3861,9 +3920,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
|||
|
||||
[[package]]
|
||||
name = "winit"
|
||||
version = "0.30.9"
|
||||
version = "0.30.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a809eacf18c8eca8b6635091543f02a5a06ddf3dad846398795460e6e0ae3cc0"
|
||||
checksum = "b0d05bd8908e14618c9609471db04007e644fd9cce6529756046cfc577f9155e"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"android-activity",
|
||||
|
@ -3913,9 +3972,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.7"
|
||||
version = "0.7.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6cb8234a863ea0e8cd7284fcdd4f145233eb00fee02bbdd9861aec44e6477bc5"
|
||||
checksum = "9e27d6ad3dac991091e4d35de9ba2d2d00647c5d0fc26c5496dee55984ae111b"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
|
|
@ -236,7 +236,10 @@ mod tests {
|
|||
|
||||
assert_eq!(sparse_set.remove(SPARSE_PAGESIZE + 2).unwrap(), 3);
|
||||
assert_eq!(sparse_set.sparse[1].as_ref().unwrap().1, 2);
|
||||
assert_eq!(sparse_set.keys(), [10, 11, 12, SPARSE_PAGESIZE, SPARSE_PAGESIZE + 1]);
|
||||
assert_eq!(
|
||||
sparse_set.keys(),
|
||||
[10, 11, 12, SPARSE_PAGESIZE, SPARSE_PAGESIZE + 1]
|
||||
);
|
||||
assert_eq!(sparse_set.values(), [1, 2, 2, 1, 2]);
|
||||
|
||||
assert_eq!(sparse_set.remove(SPARSE_PAGESIZE + 1).unwrap(), 2);
|
||||
|
@ -249,25 +252,44 @@ mod tests {
|
|||
assert_eq!(sparse_set.keys(), [10, 11, 12]);
|
||||
assert_eq!(sparse_set.values(), [1, 2, 2]);
|
||||
|
||||
|
||||
sparse_set.insert(SPARSE_PAGESIZE, 1);
|
||||
sparse_set.insert(SPARSE_PAGESIZE + 1, 2);
|
||||
sparse_set.insert(SPARSE_PAGESIZE + 2, 3);
|
||||
|
||||
assert_eq!(sparse_set.remove(10).unwrap(), 1);
|
||||
assert_eq!(sparse_set.sparse[0].as_ref().unwrap().1, 2);
|
||||
// swap-remove
|
||||
assert_eq!(sparse_set.keys(), [SPARSE_PAGESIZE + 2, 11, 12, SPARSE_PAGESIZE, SPARSE_PAGESIZE + 1]);
|
||||
// swap-remove
|
||||
assert_eq!(
|
||||
sparse_set.keys(),
|
||||
[
|
||||
SPARSE_PAGESIZE + 2,
|
||||
11,
|
||||
12,
|
||||
SPARSE_PAGESIZE,
|
||||
SPARSE_PAGESIZE + 1
|
||||
]
|
||||
);
|
||||
assert_eq!(sparse_set.values(), [3, 2, 2, 1, 2]);
|
||||
|
||||
assert_eq!(sparse_set.remove(11).unwrap(), 2);
|
||||
assert_eq!(sparse_set.sparse[0].as_ref().unwrap().1, 1);
|
||||
assert_eq!(sparse_set.keys(), [SPARSE_PAGESIZE + 2, SPARSE_PAGESIZE + 1, 12, SPARSE_PAGESIZE]);
|
||||
assert_eq!(
|
||||
sparse_set.keys(),
|
||||
[
|
||||
SPARSE_PAGESIZE + 2,
|
||||
SPARSE_PAGESIZE + 1,
|
||||
12,
|
||||
SPARSE_PAGESIZE
|
||||
]
|
||||
);
|
||||
assert_eq!(sparse_set.values(), [3, 2, 2, 1]);
|
||||
|
||||
assert_eq!(sparse_set.remove(12).unwrap(), 2);
|
||||
assert!(sparse_set.sparse[0].is_none());
|
||||
assert_eq!(sparse_set.keys(), [SPARSE_PAGESIZE + 2, SPARSE_PAGESIZE + 1, SPARSE_PAGESIZE]);
|
||||
assert_eq!(
|
||||
sparse_set.keys(),
|
||||
[SPARSE_PAGESIZE + 2, SPARSE_PAGESIZE + 1, SPARSE_PAGESIZE]
|
||||
);
|
||||
assert_eq!(sparse_set.values(), [3, 2, 1]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
include!("main.rs");
|
||||
include!("main.rs");
|
||||
|
|
|
@ -4,17 +4,20 @@ version = "0.1.0"
|
|||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.98"
|
||||
ash = "0.38.0"
|
||||
chrono = { version = "0.4.40", features = ["serde"] }
|
||||
derive_more = { version = "2.0.1", features = ["add", "add_assign", "as_ref", "deref_mut", "from", "from_str", "full", "into", "mul", "mul_assign", "not", "sum", "try_from", "try_into", "try_unwrap", "unwrap"] }
|
||||
detect-desktop-environment = "1.2.0"
|
||||
hidapi = "2.6.3"
|
||||
humansize = "2.1.3"
|
||||
metal = { version = "0.32.0", optional = true }
|
||||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
serde_json = "1.0.140"
|
||||
strum = "0.27.1"
|
||||
strum_macros = "0.27.1"
|
||||
sys-locale = "0.3.2"
|
||||
sysinfo = { version = "0.34.2", features = ["serde"] }
|
||||
thiserror = "2.0.12"
|
||||
timeago = "0.4.2"
|
||||
versions = { version = "7.0.0", features = ["serde"] }
|
||||
wgpu = "25.0.0"
|
||||
|
|
|
@ -1,35 +1,57 @@
|
|||
use serde::Serialize;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde_json::{Value, json};
|
||||
#[macro_use]
|
||||
mod modules;
|
||||
use crate::modules::{cpu, devices, external, gpu, memory, meta, network, os, storage, uptime};
|
||||
use anyhow::Result;
|
||||
pub use crate::modules::{cpu, devices, external, gpu, memory, meta, network, os, storage, uptime};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct TelemetryInfo {
|
||||
telemetry: AllInfo,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct AllInfo {
|
||||
gpu: gpu::GPUInfo,
|
||||
cpu: cpu::CPUInfo,
|
||||
cpu: Vec<cpu::CPUInfo>,
|
||||
memory: memory::MemoryInfo,
|
||||
os: os::OSInfo,
|
||||
storage: Vec<storage::StorageInfo>,
|
||||
network: network::NetworkInfo,
|
||||
external: external::ExternalInfo,
|
||||
devices: devices::DevicesInfo,
|
||||
devices: Vec<devices::DeviceInfo>,
|
||||
meta: meta::MetaInfo,
|
||||
uptime: uptime::UptimeInfo,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum TelemetryError {
|
||||
// #[error("Failed to get GPU information")]
|
||||
// GPUError(#[from] gpu::GPUError),
|
||||
#[error("Failed to get CPU information")]
|
||||
CPUError(#[from] cpu::CPUError),
|
||||
#[error("Failed to get OS information")]
|
||||
OSError(#[from] os::OSError),
|
||||
#[error("Failed to get storage information")]
|
||||
StorageError(#[from] storage::StorageError),
|
||||
// #[error("Failed to get external information")]
|
||||
// ExternalError(#[from] external::ExternalError),
|
||||
#[error("Failed to get devices information")]
|
||||
DevicesError(#[from] devices::DevicesError),
|
||||
#[error("Failed to get meta information")]
|
||||
MetaError(#[from] meta::MetaError),
|
||||
#[error("Failed to get uptime information")]
|
||||
UptimeError(#[from] uptime::UptimeError),
|
||||
#[error("Failed to build JSON for TelemetryInfo")]
|
||||
JsonError(#[from] serde_json::Error),
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_struct() -> Result<TelemetryInfo> {
|
||||
pub fn get_struct() -> Result<TelemetryInfo, TelemetryError> {
|
||||
Ok(TelemetryInfo {
|
||||
telemetry: AllInfo {
|
||||
gpu: gpu::get_struct(),
|
||||
cpu: cpu::get_struct(),
|
||||
cpu: cpu::get_struct()?,
|
||||
memory: memory::get_struct(),
|
||||
os: os::get_struct()?,
|
||||
storage: storage::get_list()?,
|
||||
|
@ -43,6 +65,6 @@ pub fn get_struct() -> Result<TelemetryInfo> {
|
|||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_json() -> Result<Value> {
|
||||
pub fn get_json() -> Result<Value, TelemetryError> {
|
||||
Ok(json!(get_struct()?))
|
||||
}
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
use serde_json;
|
||||
|
||||
fn main() {
|
||||
println!("{:#?}", telemetry::get_struct());
|
||||
//println!("{:#?}", telemetry::get_struct());
|
||||
//println!("{:#?}", telemetry::os::get_json());
|
||||
//telemetry::os::get_json();
|
||||
|
||||
match telemetry::get_struct() {
|
||||
//Ok(telemetry) => println!("{:#?}", serde_json::from_value(telemetry)),
|
||||
Ok(telemetry) => println!("{:#?}", telemetry),
|
||||
Err(e) => eprintln!("Error: {}", e),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,69 +1,67 @@
|
|||
use super::Defaults::Unknown;
|
||||
use serde::Serialize;
|
||||
use crate::modules::{FmtCores, FmtThreads};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde_json::{Value, json};
|
||||
use std::collections::HashMap;
|
||||
use sysinfo::{CpuRefreshKind, RefreshKind, System};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct ProcessorInfo {
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct CPUInfo {
|
||||
vendor: String,
|
||||
brand: String,
|
||||
total_system_cores: String,
|
||||
threads: u16,
|
||||
total_system_cores: FmtCores,
|
||||
threads: FmtThreads,
|
||||
architecture: String,
|
||||
byte_order: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct CPUInfo {
|
||||
cpus: Vec<ProcessorInfo>,
|
||||
#[derive(Debug, Error)]
|
||||
pub enum CPUError {
|
||||
#[error("No CPU information available")]
|
||||
NoCpusFound,
|
||||
#[error("Failed to build JSON for Vec<CPUInfo>")]
|
||||
JsonError(#[from] serde_json::Error),
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_struct() -> CPUInfo {
|
||||
let system =
|
||||
pub fn get_struct() -> Result<Vec<CPUInfo>, CPUError> {
|
||||
let mut system =
|
||||
System::new_with_specifics(RefreshKind::nothing().with_cpu(CpuRefreshKind::everything()));
|
||||
system.refresh_cpu_all();
|
||||
|
||||
let mut processors = Vec::new();
|
||||
let mut processor_count: HashMap<String, ProcessorInfo> = HashMap::new();
|
||||
let mut processor_map: HashMap<String, CPUInfo> = HashMap::new();
|
||||
|
||||
for cpu in system.cpus() {
|
||||
let brand = cpu.brand().trim();
|
||||
let total_cores = System::physical_core_count();
|
||||
|
||||
if processor_count.contains_key(brand) {
|
||||
processor_count.get_mut(brand).unwrap().threads += 1;
|
||||
continue;
|
||||
}
|
||||
processor_count.insert(
|
||||
brand.to_string(),
|
||||
ProcessorInfo {
|
||||
let brand = cpu.brand().trim().to_string();
|
||||
let entry = processor_map
|
||||
.entry(brand.clone())
|
||||
.or_insert_with(|| CPUInfo {
|
||||
vendor: cpu.vendor_id().trim().to_string(),
|
||||
brand: brand.to_string(),
|
||||
total_system_cores: if let Some(cores) = total_cores {
|
||||
cores.to_string()
|
||||
} else {
|
||||
Unknown.into()
|
||||
},
|
||||
threads: 1,
|
||||
brand: brand.clone(),
|
||||
total_system_cores: System::physical_core_count()
|
||||
.map(|cores| cores.into())
|
||||
.unwrap_or_else(|| 0.into()),
|
||||
threads: 0.into(),
|
||||
architecture: System::cpu_arch().trim().to_string(),
|
||||
byte_order: if cfg!(target_endian = "little") {
|
||||
String::from("little-endian")
|
||||
} else {
|
||||
String::from("big-endian")
|
||||
},
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
entry.threads += 1.into();
|
||||
}
|
||||
|
||||
for (_brand, info) in processor_count {
|
||||
processors.push(info);
|
||||
let cpus: Vec<_> = processor_map.into_values().collect();
|
||||
if cpus.is_empty() {
|
||||
return Err(CPUError::NoCpusFound);
|
||||
}
|
||||
|
||||
CPUInfo { cpus: processors }
|
||||
Ok(cpus)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_json() -> Value {
|
||||
json!(get_struct())
|
||||
pub fn get_json() -> Result<Value, CPUError> {
|
||||
Ok(json!(get_struct()?))
|
||||
}
|
||||
|
|
|
@ -1,59 +1,59 @@
|
|||
//use crate::custom_anyhow;
|
||||
use anyhow::Result;
|
||||
use serde::Serialize;
|
||||
use super::UNKNOWN;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde_json::{Value, json};
|
||||
use thiserror::Error;
|
||||
extern crate hidapi;
|
||||
use hidapi::HidApi;
|
||||
use hidapi::{HidApi, HidError};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct DeviceInfo {
|
||||
manufacturer: String,
|
||||
products: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct DevicesInfo {
|
||||
devices: Vec<DeviceInfo>,
|
||||
#[derive(Debug, Error)]
|
||||
pub enum DevicesError {
|
||||
#[error("Failed to initialize HID API: {0}")]
|
||||
HidApiInitError(#[from] HidError),
|
||||
#[error("Failed to build JSON for Vec<DeviceInfo>")]
|
||||
JsonError(#[from] serde_json::Error),
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_struct() -> Result<DevicesInfo> {
|
||||
let api = HidApi::new().unwrap();
|
||||
let mut grouped_devices: HashMap<String, Vec<String>> = HashMap::new();
|
||||
pub fn get_struct() -> Result<Vec<DeviceInfo>, DevicesError> {
|
||||
let api = HidApi::new()?;
|
||||
let mut grouped: HashMap<String, Vec<String>> = HashMap::new();
|
||||
|
||||
for device in api.device_list() {
|
||||
let manufacturer = device
|
||||
.manufacturer_string()
|
||||
.unwrap_or("Unknown")
|
||||
.to_string()
|
||||
.to_lowercase();
|
||||
let product = device.product_string().unwrap_or("Unknown").to_string();
|
||||
.unwrap_or(UNKNOWN)
|
||||
.to_ascii_lowercase();
|
||||
let product = device.product_string().unwrap_or(UNKNOWN).to_string();
|
||||
|
||||
if !manufacturer.trim().is_empty() && !product.trim().is_empty() {
|
||||
let entry = grouped_devices.entry(manufacturer).or_default();
|
||||
|
||||
if !entry.contains(&product) {
|
||||
entry.push(product);
|
||||
}
|
||||
grouped.entry(manufacturer).or_default().push(product)
|
||||
}
|
||||
}
|
||||
|
||||
let mut devices = Vec::new();
|
||||
let mut grouped_vec: Vec<_> = grouped_devices.into_iter().collect();
|
||||
grouped_vec.sort_by(|a, b| a.0.to_lowercase().cmp(&b.0.to_lowercase()));
|
||||
let mut sorted_devices: Vec<_> = grouped.into_iter().collect();
|
||||
sorted_devices.sort_by(|a, b| a.0.cmp(&b.0));
|
||||
|
||||
for (manufacturer, products) in grouped_vec {
|
||||
devices.push(DeviceInfo {
|
||||
manufacturer,
|
||||
products,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(DevicesInfo { devices })
|
||||
Ok(sorted_devices
|
||||
.into_iter()
|
||||
.map(|(manufacturer, mut products)| {
|
||||
products.sort(); // optional: sort product names
|
||||
products.dedup(); // remove duplicates
|
||||
DeviceInfo {
|
||||
manufacturer,
|
||||
products,
|
||||
}
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_json() -> Result<Value> {
|
||||
pub fn get_json() -> Result<Value, DevicesError> {
|
||||
Ok(json!(get_struct()?))
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
use serde::Serialize;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde_json::{Value, json};
|
||||
use std::{cmp::Ordering::Equal, collections::HashMap};
|
||||
use sysinfo::{System, Users};
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct SoftwareInfo {
|
||||
name: String,
|
||||
count: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct ExternalInfo {
|
||||
softwares: Vec<SoftwareInfo>,
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use serde::Serialize;
|
||||
use serde::{Serialize, Serializer, Deserialize, Deserializer, de::Error as DeError};
|
||||
use std::{
|
||||
fmt::{Debug, Display, Formatter, Result as FmtResult},
|
||||
ops::Deref,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Serialize)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||
pub enum TargetPointerWidth {
|
||||
W32Bit,
|
||||
W64Bit,
|
||||
|
@ -40,12 +40,26 @@ impl Debug for FmtOSArchitecture {
|
|||
impl Serialize for FmtOSArchitecture {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for FmtOSArchitecture {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
match s.as_str() {
|
||||
"32 Bit" => Ok(FmtOSArchitecture(TargetPointerWidth::W32Bit)),
|
||||
"64 Bit" => Ok(FmtOSArchitecture(TargetPointerWidth::W64Bit)),
|
||||
_ => Err(DeError::custom(format!("Invalid architecture: {}", s))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for FmtOSArchitecture {
|
||||
type Target = TargetPointerWidth;
|
||||
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
use serde::Serialize;
|
||||
use std::{
|
||||
fmt::{Debug, Display, Formatter, Result as FmtResult},
|
||||
ops::Deref,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct FmtBytes(pub u64);
|
||||
|
||||
impl Display for FmtBytes {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
use humansize::{DECIMAL, format_size};
|
||||
write!(f, "{}", format_size(self.0, DECIMAL))
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for FmtBytes {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for FmtBytes {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for FmtBytes {
|
||||
type Target = u64;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
use chrono::{DateTime, Local, TimeZone, Utc};
|
||||
use serde::Serialize;
|
||||
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
||||
use std::{
|
||||
fmt::{Debug, Display, Formatter, Result as FMTResult},
|
||||
ops::Deref,
|
||||
};
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct DateTimeInfo {
|
||||
date: String,
|
||||
time: String,
|
||||
|
@ -46,12 +46,31 @@ where
|
|||
{
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, Tz> Deserialize<'de> for FmtDateTime<Tz>
|
||||
where
|
||||
Tz: TimeZone,
|
||||
DateTime<Tz>: ToString + std::str::FromStr,
|
||||
<DateTime<Tz> as std::str::FromStr>::Err: std::fmt::Display,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
// 1. Pull a String out of the deserializer
|
||||
let s = String::deserialize(deserializer)?;
|
||||
// 2. Parse it, mapping any parse-error into a Serde error
|
||||
<DateTime<Tz> as std::str::FromStr>::from_str(&s) // explicit, no ambiguity
|
||||
.map(FmtDateTime)
|
||||
.map_err(serde::de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Tz: TimeZone> Deref for FmtDateTime<Tz> {
|
||||
type Target = DateTime<Tz>;
|
||||
|
||||
|
|
|
@ -1,59 +1,44 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
use serde::{Serialize, Deserialize};
|
||||
use detect_desktop_environment::DesktopEnvironment;
|
||||
use serde::{Serialize, Serializer};
|
||||
use std::{
|
||||
fmt::{Debug, Display, Formatter, Result as FmtResult},
|
||||
ops::Deref,
|
||||
};
|
||||
use strum_macros::EnumString;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub struct SerdeDE(pub DesktopEnvironment);
|
||||
|
||||
impl Serialize for SerdeDE {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
serializer.serialize_str(&format!("{:?}", self.0))
|
||||
}
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, EnumString)]
|
||||
#[strum(serialize_all = "PascalCase", ascii_case_insensitive)]
|
||||
#[non_exhaustive]
|
||||
pub enum FmtDE {
|
||||
Cinnamon,
|
||||
Cosmic,
|
||||
CosmicEpoch,
|
||||
Dde,
|
||||
Ede,
|
||||
Endless,
|
||||
Enlightenment,
|
||||
Gnome,
|
||||
Hyprland,
|
||||
Kde,
|
||||
Lxde,
|
||||
Lxqt,
|
||||
MacOs,
|
||||
Mate,
|
||||
Old,
|
||||
Pantheon,
|
||||
Razor,
|
||||
Rox,
|
||||
Sway,
|
||||
Tde,
|
||||
Unity,
|
||||
Windows,
|
||||
Xfce,
|
||||
}
|
||||
|
||||
impl SerdeDE {
|
||||
pub fn detect() -> Option<Self> {
|
||||
DesktopEnvironment::detect().map(SerdeDE)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub struct FmtDE(pub SerdeDE);
|
||||
|
||||
impl FmtDE {
|
||||
pub fn detect() -> Option<Self> {
|
||||
SerdeDE::detect().map(FmtDE)
|
||||
DesktopEnvironment::detect().and_then(|inner_de| {
|
||||
let s = format!("{:?}", inner_de);
|
||||
|
||||
FmtDE::from_str(&s).ok()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for FmtDE {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
write!(f, "{:?}", self.0.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for FmtDE {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for FmtDE {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for FmtDE {
|
||||
type Target = SerdeDE;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
pub mod architecture;
|
||||
pub mod bytes;
|
||||
pub mod date_time;
|
||||
pub mod desktop_environment;
|
||||
pub mod offset_time;
|
||||
pub mod relative_time;
|
||||
pub mod version;
|
||||
pub mod numbers;
|
54
subcrates/telemetry/src/modules/formatted/numbers.rs
Normal file
54
subcrates/telemetry/src/modules/formatted/numbers.rs
Normal file
|
@ -0,0 +1,54 @@
|
|||
use derive_more::{
|
||||
Add, AddAssign, Deref, Div, DivAssign, From, Mul, MulAssign, Sub, SubAssign,
|
||||
};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
|
||||
|
||||
enum DisplayKind {
|
||||
Plural(&'static str, &'static str),
|
||||
HumanBytes,
|
||||
}
|
||||
|
||||
macro_rules! define_fmt_wrapper {
|
||||
($name:ident, $ty:ty, $display_kind:expr) => {
|
||||
#[derive(
|
||||
Copy, Clone, PartialEq, Eq, PartialOrd, Ord,
|
||||
Add, Sub, Mul, Div,
|
||||
AddAssign, SubAssign, MulAssign, DivAssign,
|
||||
From, Deref, Serialize, Deserialize
|
||||
)]
|
||||
pub struct $name(pub $ty);
|
||||
|
||||
impl $name {
|
||||
#[allow(dead_code)]
|
||||
pub fn new(value: $ty) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for $name {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
match $display_kind {
|
||||
DisplayKind::Plural(singular, plural) => {
|
||||
let label = if self.0 == 1 { singular } else { plural };
|
||||
write!(f, "{} {}", self.0, label)
|
||||
},
|
||||
DisplayKind::HumanBytes => {
|
||||
use humansize::{format_size, DECIMAL};
|
||||
write!(f, "{}", format_size(self.0, DECIMAL))
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for $name {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
define_fmt_wrapper!(FmtThreads, u16, DisplayKind::Plural("Thread", "Threads"));
|
||||
define_fmt_wrapper!(FmtCores, usize, DisplayKind::Plural("Core", "Cores"));
|
||||
define_fmt_wrapper!(FmtBytes, u64, DisplayKind::HumanBytes);
|
|
@ -1,20 +1,15 @@
|
|||
use chrono::{DateTime, Local, Offset};
|
||||
use serde::Serialize;
|
||||
use derive_more::{Deref, Display, From};
|
||||
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
fmt::{Debug, Display, Formatter, Result as FmtResult},
|
||||
ops::Deref,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Copy, Clone, From, Deref, Display)]
|
||||
#[display("UTC {}", "_0.offset()")]
|
||||
pub struct FmtOffsetTime(pub DateTime<Local>);
|
||||
|
||||
impl Display for FmtOffsetTime {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
write!(f, "UTC{}", self.0.offset())
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for FmtOffsetTime {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
Display::fmt(self, f)
|
||||
|
@ -24,17 +19,28 @@ impl Debug for FmtOffsetTime {
|
|||
impl Serialize for FmtOffsetTime {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for FmtOffsetTime {
|
||||
type Target = DateTime<Local>;
|
||||
impl<'de> Deserialize<'de> for FmtOffsetTime {
|
||||
fn deserialize<D>(deserializer: D) -> Result<FmtOffsetTime, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
// Deserialize the input as a string
|
||||
let s = String::deserialize(deserializer)?;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
// Attempt to parse the string into a DateTime<Local>
|
||||
match DateTime::parse_from_rfc3339(&s) {
|
||||
Ok(dt) => Ok(FmtOffsetTime(dt.with_timezone(&Local))),
|
||||
Err(e) => Err(serde::de::Error::custom(format!(
|
||||
"Failed to parse DateTime: {}",
|
||||
e
|
||||
))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,21 +54,13 @@ impl PartialEq for FmtOffsetTime {
|
|||
impl PartialOrd for FmtOffsetTime {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(
|
||||
self.0
|
||||
.offset()
|
||||
.fix()
|
||||
.local_minus_utc()
|
||||
.cmp(&other.0.offset().fix().local_minus_utc()),
|
||||
self.0.offset().fix().local_minus_utc().cmp(&other.0.offset().fix().local_minus_utc()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for FmtOffsetTime {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.0
|
||||
.offset()
|
||||
.fix()
|
||||
.local_minus_utc()
|
||||
.cmp(&other.0.offset().fix().local_minus_utc())
|
||||
self.0.offset().fix().local_minus_utc().cmp(&other.0.offset().fix().local_minus_utc())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
use serde::Serialize;
|
||||
use derive_more::{From, Deref, with_trait::Display as Display};
|
||||
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
||||
use std::{
|
||||
fmt::{Debug, Display, Formatter, Result as FmtResult},
|
||||
ops::Deref,
|
||||
fmt::{Debug, Formatter, Result as FmtResult},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[derive(
|
||||
Clone,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
From,
|
||||
Deref,
|
||||
)]
|
||||
pub struct FmtRelativeTime(pub Duration);
|
||||
|
||||
impl Display for FmtRelativeTime {
|
||||
|
@ -25,16 +33,18 @@ impl Debug for FmtRelativeTime {
|
|||
impl Serialize for FmtRelativeTime {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.to_string())
|
||||
serializer.serialize_u64(self.0.as_secs())
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for FmtRelativeTime {
|
||||
type Target = Duration;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
impl<'de> Deserialize<'de> for FmtRelativeTime {
|
||||
fn deserialize<D>(deserializer: D) -> Result<FmtRelativeTime, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let secs = u64::deserialize(deserializer)?;
|
||||
Ok(FmtRelativeTime(Duration::from_secs(secs)))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,38 +1,38 @@
|
|||
use serde::Serialize;
|
||||
use derive_more::{Display, From, Deref, with_trait::Display as TDisplay};
|
||||
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
||||
use std::{
|
||||
fmt::{Debug, Display, Formatter, Result as FmtResult},
|
||||
ops::Deref,
|
||||
fmt::{Debug, Formatter, Result as FmtResult},
|
||||
str::FromStr,
|
||||
};
|
||||
use versions::Versioning;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, From, Deref, Display)]
|
||||
#[display("{_0}")]
|
||||
pub struct FmtVersion(pub Versioning);
|
||||
|
||||
impl Display for FmtVersion {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for FmtVersion {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
Display::fmt(self, f)
|
||||
TDisplay::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for FmtVersion {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for FmtVersion {
|
||||
type Target = Versioning;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
impl<'de> Deserialize<'de> for FmtVersion {
|
||||
fn deserialize<D>(deserializer: D) -> Result<FmtVersion, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
Versioning::from_str(&s)
|
||||
.map(FmtVersion)
|
||||
.map_err(serde::de::Error::custom)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
use super::Defaults::Unknown;
|
||||
use serde::Serialize;
|
||||
use super::UNKNOWN;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde_json::{Value, json};
|
||||
use wgpu;
|
||||
use winit::{
|
||||
|
@ -11,13 +11,13 @@ use winit::{
|
|||
|
||||
mod vram;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct DriverInfo {
|
||||
version: String,
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct AdapterInfo {
|
||||
vendor: String,
|
||||
model: String,
|
||||
|
@ -26,13 +26,13 @@ pub struct AdapterInfo {
|
|||
display: DisplayInfo,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct GPUInfo {
|
||||
supported_backends: Vec<String>,
|
||||
gpus: Vec<AdapterInfo>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Default)]
|
||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||
pub struct DisplayInfo {
|
||||
resolution: String,
|
||||
refresh_rate: String,
|
||||
|
@ -48,11 +48,11 @@ impl ApplicationHandler for DisplayInfo {
|
|||
self.refresh_rate = if let Some(refresh) = refresh_rate {
|
||||
format!("{} hz", refresh / 1000)
|
||||
} else {
|
||||
Unknown.into()
|
||||
UNKNOWN.to_string()
|
||||
}
|
||||
} else {
|
||||
self.resolution = Unknown.into();
|
||||
self.refresh_rate = Unknown.into();
|
||||
self.resolution = UNKNOWN.to_string();
|
||||
self.refresh_rate = UNKNOWN.to_string();
|
||||
}
|
||||
|
||||
event_loop.exit();
|
||||
|
@ -75,7 +75,7 @@ fn vendor_name(vendor: u32) -> &'static str {
|
|||
0x13B5 => "ARM(Advanced RISC Machines)",
|
||||
0x5143 => "Qualcomm(Quality Communications)",
|
||||
0x1010 => "Apple Inc.",
|
||||
_ => "Unknown",
|
||||
_ => UNKNOWN,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use super::super::Defaults::Unknown;
|
||||
use super::super::UNKNOWN;
|
||||
use ash::vk::{API_VERSION_1_2, ApplicationInfo, InstanceCreateInfo, MemoryHeapFlags};
|
||||
use humansize::{DECIMAL, make_format};
|
||||
|
||||
|
@ -62,6 +62,6 @@ pub fn get(vendor: u32, device_id: u32) -> String {
|
|||
match vendor {
|
||||
0x10DE | 0x1002 | 0x8086 | 0x5143 => formatter(get_vulkan(device_id)),
|
||||
0x1010 => formatter(get_metal()),
|
||||
_ => Unknown.into(),
|
||||
_ => UNKNOWN.to_string(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
#[macro_export]
|
||||
macro_rules! custom_anyhow {
|
||||
($fmt:literal $(, $arg:expr)* $(,)?) => {
|
||||
::anyhow::anyhow!(
|
||||
concat!($fmt, " (file: {}, line: {})"),
|
||||
$($arg,)*
|
||||
file!(),
|
||||
line!()
|
||||
)
|
||||
};
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
pub mod custom_anyhow;
|
|
@ -1,9 +1,9 @@
|
|||
use crate::modules::FmtBytes;
|
||||
use serde::Serialize;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde_json::{Value, json};
|
||||
use sysinfo::System;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PhysicalInfo {
|
||||
total: FmtBytes,
|
||||
used: FmtBytes,
|
||||
|
@ -11,14 +11,14 @@ pub struct PhysicalInfo {
|
|||
available: FmtBytes,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct VirtualInfo {
|
||||
total: FmtBytes,
|
||||
used: FmtBytes,
|
||||
free: FmtBytes,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct MemoryInfo {
|
||||
physical: PhysicalInfo,
|
||||
virtual_swap: VirtualInfo,
|
||||
|
@ -26,7 +26,8 @@ pub struct MemoryInfo {
|
|||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_struct() -> MemoryInfo {
|
||||
let system = System::new_all();
|
||||
let mut system = System::new_all();
|
||||
system.refresh_memory();
|
||||
|
||||
MemoryInfo {
|
||||
physical: PhysicalInfo {
|
||||
|
|
|
@ -1,24 +1,31 @@
|
|||
use crate::{custom_anyhow, modules::FmtVersion};
|
||||
use anyhow::Result;
|
||||
use serde::Serialize;
|
||||
use crate::modules::FmtVersion;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde_json::{Value, json};
|
||||
use sys_locale::get_locale;
|
||||
use thiserror::Error;
|
||||
use versions::Versioning;
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/built.rs"));
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct MetaInfo {
|
||||
version: FmtVersion,
|
||||
commit_hash: String,
|
||||
locale: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum MetaError {
|
||||
#[error("Invalid Semver version")]
|
||||
InvalidVersion,
|
||||
#[error("Failed to build JSON for MetaInfo")]
|
||||
JsonError(#[from] serde_json::Error),
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_struct() -> Result<MetaInfo> {
|
||||
pub fn get_struct() -> Result<MetaInfo, MetaError> {
|
||||
let locale = get_locale().unwrap_or_else(|| String::from("en-US"));
|
||||
let version = Versioning::new(env!("CARGO_PKG_VERSION"))
|
||||
.ok_or(custom_anyhow!("Invalid version").context("Invalid Semver version"))?;
|
||||
let version = Versioning::new(env!("CARGO_PKG_VERSION")).ok_or(MetaError::InvalidVersion)?;
|
||||
|
||||
Ok(MetaInfo {
|
||||
version: FmtVersion(version),
|
||||
|
@ -28,6 +35,6 @@ pub fn get_struct() -> Result<MetaInfo> {
|
|||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_json() -> Result<Value> {
|
||||
pub fn get_json() -> Result<Value, MetaError> {
|
||||
Ok(json!(get_struct()?))
|
||||
}
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
|
||||
|
||||
pub mod cpu;
|
||||
pub mod devices;
|
||||
pub mod external;
|
||||
pub mod formatted;
|
||||
pub mod gpu;
|
||||
pub mod macros;
|
||||
pub mod memory;
|
||||
pub mod meta;
|
||||
pub mod network;
|
||||
|
@ -16,27 +13,14 @@ pub mod uptime;
|
|||
#[allow(unused_imports)]
|
||||
pub use formatted::{
|
||||
architecture::FmtOSArchitecture,
|
||||
bytes::FmtBytes,
|
||||
numbers::FmtBytes,
|
||||
date_time::{FmtDateTime, IntoDateTime},
|
||||
desktop_environment::FmtDE,
|
||||
offset_time::FmtOffsetTime,
|
||||
relative_time::FmtRelativeTime,
|
||||
version::FmtVersion,
|
||||
numbers::FmtCores,
|
||||
numbers::FmtThreads,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Defaults {
|
||||
Unknown,
|
||||
}
|
||||
|
||||
impl Display for Defaults {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
write!(f, "{:?}", self)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Defaults> for String {
|
||||
fn from(value: Defaults) -> Self {
|
||||
value.to_string()
|
||||
}
|
||||
}
|
||||
pub const UNKNOWN: &str = "Unknown";
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use serde::Serialize;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde_json::{Value, json};
|
||||
use sysinfo::Networks;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct NetworkInfo {
|
||||
adapters: Vec<String>,
|
||||
}
|
||||
|
@ -10,11 +10,7 @@ pub struct NetworkInfo {
|
|||
#[allow(dead_code)]
|
||||
pub fn get_struct() -> NetworkInfo {
|
||||
let networks = Networks::new_with_refreshed_list();
|
||||
let mut adapters = Vec::new();
|
||||
|
||||
for (interface_name, _network_data) in &networks {
|
||||
adapters.push(interface_name.to_string());
|
||||
}
|
||||
let adapters = networks.iter().map(|(name, _)| name.to_string()).collect();
|
||||
|
||||
NetworkInfo { adapters }
|
||||
}
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
use super::Defaults::Unknown;
|
||||
use crate::{
|
||||
custom_anyhow,
|
||||
modules::{FmtDE, FmtOSArchitecture},
|
||||
};
|
||||
use anyhow::Result;
|
||||
use serde::Serialize;
|
||||
use super::UNKNOWN;
|
||||
use crate::modules::{FmtDE, FmtOSArchitecture};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde_json::{Value, json};
|
||||
use sysinfo::System;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct OSInfo {
|
||||
name: String,
|
||||
edition: String,
|
||||
|
@ -18,20 +15,28 @@ pub struct OSInfo {
|
|||
desktop_environment: Option<FmtDE>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum OSError {
|
||||
#[error("Unsupported pointer width: 16 bit systems are not supported")]
|
||||
UnsupportedPointerWidth,
|
||||
#[error("Failed to build JSON for OSInfo")]
|
||||
JsonError(#[from] serde_json::Error),
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_struct() -> Result<OSInfo> {
|
||||
let architecture = if cfg!(target_pointer_width = "64") {
|
||||
Ok(FmtOSArchitecture::W64_BIT)
|
||||
} else if cfg!(target_pointer_width = "32") {
|
||||
Ok(FmtOSArchitecture::W32_BIT)
|
||||
} else {
|
||||
Err(custom_anyhow!("Unsupported pointer width").context("16 bit systems are not supported"))
|
||||
pub fn get_struct() -> Result<OSInfo, OSError> {
|
||||
let architecture = match std::mem::size_of::<usize>() {
|
||||
8 => Ok(FmtOSArchitecture::W64_BIT),
|
||||
4 => Ok(FmtOSArchitecture::W32_BIT),
|
||||
_ => Err(OSError::UnsupportedPointerWidth),
|
||||
}?;
|
||||
|
||||
let kernel = if cfg!(target_os = "linux") || cfg!(target_os = "macos") {
|
||||
Some(System::kernel_long_version())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let desktop_environment = if cfg!(target_os = "linux") {
|
||||
FmtDE::detect()
|
||||
} else {
|
||||
|
@ -39,9 +44,9 @@ pub fn get_struct() -> Result<OSInfo> {
|
|||
};
|
||||
|
||||
Ok(OSInfo {
|
||||
name: System::name().unwrap_or(Unknown.into()),
|
||||
edition: System::long_os_version().unwrap_or(Unknown.into()),
|
||||
version: System::os_version().unwrap_or(Unknown.into()),
|
||||
name: System::name().unwrap_or(UNKNOWN.to_string()),
|
||||
edition: System::long_os_version().unwrap_or(UNKNOWN.to_string()),
|
||||
version: System::os_version().unwrap_or(UNKNOWN.to_string()),
|
||||
architecture,
|
||||
kernel,
|
||||
desktop_environment,
|
||||
|
@ -49,6 +54,6 @@ pub fn get_struct() -> Result<OSInfo> {
|
|||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_json() -> Result<Value> {
|
||||
pub fn get_json() -> Result<Value, OSError> {
|
||||
Ok(json!(get_struct()?))
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use crate::{custom_anyhow, modules::FmtBytes};
|
||||
use anyhow::Result;
|
||||
use serde::Serialize;
|
||||
use crate::modules::FmtBytes;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde_json::{Value, json};
|
||||
pub use sysinfo::DiskKind;
|
||||
use sysinfo::Disks;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct StorageInfo {
|
||||
name: String,
|
||||
mount_point: String,
|
||||
|
@ -14,33 +14,36 @@ pub struct StorageInfo {
|
|||
total: FmtBytes,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_list() -> Result<Vec<StorageInfo>> {
|
||||
let disks = Disks::new_with_refreshed_list();
|
||||
let mut drive_data = Vec::new();
|
||||
#[derive(Debug, Error)]
|
||||
pub enum StorageError {
|
||||
#[error("No storage drives found")]
|
||||
NoDisksFound,
|
||||
#[error("Failed to build JSON for Vec<StorageInfo>")]
|
||||
JsonError(#[from] serde_json::Error),
|
||||
}
|
||||
|
||||
for disk in disks.list() {
|
||||
drive_data.push(StorageInfo {
|
||||
name: format!("{:?}", disk.name()).trim_matches('\"').to_string(),
|
||||
mount_point: format!("{:?}", disk.mount_point())
|
||||
.replace("\\", "")
|
||||
.trim_matches('\"')
|
||||
.to_string(),
|
||||
#[allow(dead_code)]
|
||||
pub fn get_list() -> Result<Vec<StorageInfo>, StorageError> {
|
||||
let disks = Disks::new_with_refreshed_list();
|
||||
let disk_list = disks.list();
|
||||
|
||||
if disk_list.is_empty() {
|
||||
return Err(StorageError::NoDisksFound);
|
||||
}
|
||||
|
||||
Ok(disk_list
|
||||
.iter()
|
||||
.map(|disk| StorageInfo {
|
||||
name: disk.name().to_string_lossy().into_owned(),
|
||||
mount_point: disk.mount_point().to_string_lossy().replace('\\', ""),
|
||||
disk_kind: disk.kind(),
|
||||
space_left: FmtBytes(disk.available_space()),
|
||||
total: FmtBytes(disk.total_space()),
|
||||
});
|
||||
}
|
||||
|
||||
if drive_data.is_empty() {
|
||||
return Err(custom_anyhow!("No storage drives found")
|
||||
.context("Drive_data is empty, expected disks.list() to return non-zero at line 39"));
|
||||
}
|
||||
|
||||
Ok(drive_data)
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_json() -> Result<Value> {
|
||||
pub fn get_json() -> Result<Value, StorageError> {
|
||||
Ok(json!(get_list()?))
|
||||
}
|
||||
|
|
|
@ -1,54 +1,71 @@
|
|||
use crate::{
|
||||
custom_anyhow,
|
||||
modules::{FmtDateTime, FmtOffsetTime, FmtRelativeTime},
|
||||
};
|
||||
use anyhow::Result;
|
||||
use chrono::{DateTime, Local, Utc};
|
||||
use serde::Serialize;
|
||||
use crate::modules::{FmtDateTime, FmtOffsetTime, FmtRelativeTime};
|
||||
use chrono::{DateTime, Local, Utc, TimeZone};
|
||||
use serde::{Serialize, Serializer, Deserialize};
|
||||
use serde_json::{Value, json};
|
||||
use std::time::Duration as StdDuration;
|
||||
use std::{
|
||||
time::Duration as StdDuration,
|
||||
fmt::Display,
|
||||
};
|
||||
use sysinfo::System;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
fn serialize_datetime<S, Tz>(date: &DateTime<Tz>, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
Tz::Offset: Display,
|
||||
Tz: TimeZone,
|
||||
{
|
||||
let formatted = date.format("%+").to_string(); // Format as RFC 3339
|
||||
serializer.serialize_str(&formatted)
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct DateInfo {
|
||||
#[serde(serialize_with = "serialize_datetime")]
|
||||
time_offset: FmtOffsetTime,
|
||||
#[serde(serialize_with = "serialize_datetime")]
|
||||
local_date_time: FmtDateTime<Local>,
|
||||
#[serde(serialize_with = "serialize_datetime")]
|
||||
utc_date_time: FmtDateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct UptimeInfo {
|
||||
boot: DateInfo,
|
||||
now: DateInfo,
|
||||
relative: FmtRelativeTime,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum UptimeError {
|
||||
#[error("Invalid or out of range timestamp: check seconds < 8_220_000_000_000")]
|
||||
InvalidTimestamp,
|
||||
#[error("Failed to build JSON for UptimeInfo")]
|
||||
JsonError(#[from] serde_json::Error),
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_struct() -> Result<UptimeInfo> {
|
||||
let boot_time_utc = DateTime::<Utc>::from_timestamp(System::boot_time() as i64, 0).ok_or(
|
||||
custom_anyhow!("Invalid, or out of range timestamp")
|
||||
.context("Invalid timestamp: check seconds < 8_220_000_000_000"),
|
||||
)?;
|
||||
pub fn get_struct() -> Result<UptimeInfo, UptimeError> {
|
||||
let boot_time_utc = DateTime::<Utc>::from_timestamp(System::boot_time() as i64, 0)
|
||||
.ok_or(UptimeError::InvalidTimestamp)?;
|
||||
let boot_time_local: DateTime<Local> = boot_time_utc.with_timezone(&Local);
|
||||
let relative_time =
|
||||
StdDuration::from_secs((Local::now() - boot_time_local).num_seconds() as u64);
|
||||
|
||||
let make_info = |utc_dt: DateTime<Utc>| DateInfo {
|
||||
time_offset: FmtOffsetTime(Local::now()),
|
||||
local_date_time: FmtDateTime(utc_dt.with_timezone(&Local)),
|
||||
utc_date_time: FmtDateTime(utc_dt),
|
||||
};
|
||||
|
||||
Ok(UptimeInfo {
|
||||
boot: DateInfo {
|
||||
time_offset: FmtOffsetTime(Local::now()),
|
||||
local_date_time: FmtDateTime(boot_time_local),
|
||||
utc_date_time: FmtDateTime(boot_time_utc),
|
||||
},
|
||||
now: DateInfo {
|
||||
time_offset: FmtOffsetTime(Local::now()),
|
||||
local_date_time: FmtDateTime(Local::now()),
|
||||
utc_date_time: FmtDateTime(Utc::now()),
|
||||
},
|
||||
boot: make_info(boot_time_utc),
|
||||
now: make_info(Utc::now()),
|
||||
relative: FmtRelativeTime(relative_time),
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_json() -> Result<Value> {
|
||||
pub fn get_json() -> Result<Value, UptimeError> {
|
||||
Ok(json!(get_struct()?))
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ impl LoggerConfig {
|
|||
self.log_json_show_message = i;
|
||||
self
|
||||
}
|
||||
|
||||
|
||||
pub fn log_json_show_additional_fields(mut self, i: bool) -> Self {
|
||||
self.log_json_show_additional_fields = i;
|
||||
self
|
||||
|
@ -96,7 +96,7 @@ impl Default for LoggerConfig {
|
|||
log_json_show_timestamp: false,
|
||||
log_json_show_level: false,
|
||||
log_json_show_message: false,
|
||||
log_json_show_additional_fields: false
|
||||
log_json_show_additional_fields: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ where
|
|||
level,
|
||||
message,
|
||||
#[cfg(feature = "json")]
|
||||
additional_fields
|
||||
additional_fields,
|
||||
});
|
||||
|
||||
if let LogEvent::Log(ref entry) = log_entry {
|
||||
|
@ -212,13 +212,7 @@ impl Logger {
|
|||
for msg in rx {
|
||||
match msg {
|
||||
LogEvent::Log(mut entry) => {
|
||||
println!(
|
||||
"{}",
|
||||
format_entry(
|
||||
&mut entry,
|
||||
&config_clone
|
||||
)
|
||||
);
|
||||
println!("{}", format_entry(&mut entry, &config_clone));
|
||||
}
|
||||
LogEvent::Shutdown => break,
|
||||
}
|
||||
|
@ -298,12 +292,12 @@ fn format_entry(entry: &mut LogEntry, log_config: &LoggerConfig) -> String {
|
|||
if log_config.log_use_json {
|
||||
return format_entry_json(entry, log_config);
|
||||
}
|
||||
|
||||
|
||||
if log_config.log_to_stdout || log_config.log_to_file {
|
||||
return format_entry_string(entry, log_config);
|
||||
} else {
|
||||
return String::new();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn format_entry_string(entry: &LogEntry, log_config: &LoggerConfig) -> String {
|
||||
|
@ -327,7 +321,10 @@ fn format_entry_json(entry: &mut LogEntry, log_config: &LoggerConfig) -> String
|
|||
let mut json_object = serde_json::Map::new();
|
||||
|
||||
if log_config.log_json_show_timestamp {
|
||||
json_object.insert("timestamp".to_string(), Value::String(DateTime::<Utc>::from(entry.timestamp).to_rfc3339()));
|
||||
json_object.insert(
|
||||
"timestamp".to_string(),
|
||||
Value::String(DateTime::<Utc>::from(entry.timestamp).to_rfc3339()),
|
||||
);
|
||||
}
|
||||
|
||||
if log_config.log_json_show_level {
|
||||
|
@ -335,7 +332,10 @@ fn format_entry_json(entry: &mut LogEntry, log_config: &LoggerConfig) -> String
|
|||
}
|
||||
|
||||
if log_config.log_json_show_message {
|
||||
json_object.insert("message".to_string(), Value::String(entry.message.to_string()));
|
||||
json_object.insert(
|
||||
"message".to_string(),
|
||||
Value::String(entry.message.to_string()),
|
||||
);
|
||||
}
|
||||
|
||||
if log_config.log_json_show_additional_fields {
|
||||
|
@ -343,4 +343,4 @@ fn format_entry_json(entry: &mut LogEntry, log_config: &LoggerConfig) -> String
|
|||
}
|
||||
|
||||
serde_json::to_string(&json_object).unwrap()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use pretty_assertions::assert_eq;
|
||||
use tracing::Level;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Map;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use tracing::Level;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -126,9 +126,15 @@ fn test_logger_sequential_consistency_json() {
|
|||
|
||||
for log in logger.get_logs(LogQuery::All) {
|
||||
let mut json_object = serde_json::Map::new();
|
||||
json_object.insert("timestamp".to_string(), Value::String(DateTime::<Utc>::from(log.timestamp).to_rfc3339()));
|
||||
json_object.insert(
|
||||
"timestamp".to_string(),
|
||||
Value::String(DateTime::<Utc>::from(log.timestamp).to_rfc3339()),
|
||||
);
|
||||
json_object.insert("level".to_string(), Value::String(log.level.to_string()));
|
||||
json_object.insert("message".to_string(), Value::String(log.message.to_string()));
|
||||
json_object.insert(
|
||||
"message".to_string(),
|
||||
Value::String(log.message.to_string()),
|
||||
);
|
||||
|
||||
log_json.push(json_object);
|
||||
}
|
||||
|
@ -136,4 +142,4 @@ fn test_logger_sequential_consistency_json() {
|
|||
for log in log_json {
|
||||
serde_json::to_string(&log).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue