|
| 1 | +use crate::ironvar::Namespace; |
1 | 2 | use crate::modules::sysinfo::Interval;
|
2 | 3 | use crate::{lock, register_client};
|
| 4 | +use color_eyre::{Report, Result}; |
3 | 5 | use std::cmp::Ordering;
|
4 | 6 | use std::collections::HashMap;
|
5 | 7 | use std::fmt::Debug;
|
6 |
| -use std::sync::Mutex; |
| 8 | +use std::str::FromStr; |
| 9 | +use std::sync::{Arc, Mutex}; |
7 | 10 | use sysinfo::{Components, Disks, LoadAvg, Networks, RefreshKind, System};
|
8 | 11 |
|
9 | 12 | #[repr(u64)]
|
@@ -43,6 +46,21 @@ pub enum Function {
|
43 | 46 | Name(String),
|
44 | 47 | }
|
45 | 48 |
|
| 49 | +impl FromStr for Function { |
| 50 | + type Err = (); |
| 51 | + |
| 52 | + fn from_str(s: &str) -> Result<Self, Self::Err> { |
| 53 | + match s.to_lowercase().as_str() { |
| 54 | + "sum" => Ok(Self::Sum), |
| 55 | + "min" => Ok(Self::Min), |
| 56 | + "max" => Ok(Self::Max), |
| 57 | + "mean" => Ok(Self::Mean), |
| 58 | + "" => Err(()), |
| 59 | + _ => Ok(Self::Name(s.to_string())), |
| 60 | + } |
| 61 | + } |
| 62 | +} |
| 63 | + |
46 | 64 | #[derive(Debug)]
|
47 | 65 | pub struct ValueSet {
|
48 | 66 | values: HashMap<Box<str>, Value>,
|
@@ -388,3 +406,212 @@ register_client!(Client, sys_info);
|
388 | 406 | const fn c_to_f(c: f64) -> f64 {
|
389 | 407 | c / 5.0 * 9.0 + 32.0
|
390 | 408 | }
|
| 409 | + |
| 410 | +#[derive(Debug, Clone, Copy, PartialEq, Eq)] |
| 411 | +pub enum TokenType { |
| 412 | + CpuFrequency, |
| 413 | + CpuPercent, |
| 414 | + |
| 415 | + MemoryFree, |
| 416 | + MemoryAvailable, |
| 417 | + MemoryTotal, |
| 418 | + MemoryUsed, |
| 419 | + MemoryPercent, |
| 420 | + |
| 421 | + SwapFree, |
| 422 | + SwapTotal, |
| 423 | + SwapUsed, |
| 424 | + SwapPercent, |
| 425 | + |
| 426 | + TempC, |
| 427 | + TempF, |
| 428 | + |
| 429 | + DiskFree, |
| 430 | + DiskTotal, |
| 431 | + DiskUsed, |
| 432 | + DiskPercent, |
| 433 | + DiskRead, |
| 434 | + DiskWrite, |
| 435 | + |
| 436 | + NetDown, |
| 437 | + NetUp, |
| 438 | + |
| 439 | + LoadAverage1, |
| 440 | + LoadAverage5, |
| 441 | + LoadAverage15, |
| 442 | + Uptime, |
| 443 | +} |
| 444 | + |
| 445 | +impl FromStr for TokenType { |
| 446 | + type Err = Report; |
| 447 | + |
| 448 | + fn from_str(s: &str) -> Result<Self> { |
| 449 | + match s { |
| 450 | + "cpu_frequency" => Ok(Self::CpuFrequency), |
| 451 | + "cpu_percent" => Ok(Self::CpuPercent), |
| 452 | + |
| 453 | + "memory_free" => Ok(Self::MemoryFree), |
| 454 | + "memory_available" => Ok(Self::MemoryAvailable), |
| 455 | + "memory_total" => Ok(Self::MemoryTotal), |
| 456 | + "memory_used" => Ok(Self::MemoryUsed), |
| 457 | + "memory_percent" => Ok(Self::MemoryPercent), |
| 458 | + |
| 459 | + "swap_free" => Ok(Self::SwapFree), |
| 460 | + "swap_total" => Ok(Self::SwapTotal), |
| 461 | + "swap_used" => Ok(Self::SwapUsed), |
| 462 | + "swap_percent" => Ok(Self::SwapPercent), |
| 463 | + |
| 464 | + "temp_c" => Ok(Self::TempC), |
| 465 | + "temp_f" => Ok(Self::TempF), |
| 466 | + |
| 467 | + "disk_free" => Ok(Self::DiskFree), |
| 468 | + "disk_total" => Ok(Self::DiskTotal), |
| 469 | + "disk_used" => Ok(Self::DiskUsed), |
| 470 | + "disk_percent" => Ok(Self::DiskPercent), |
| 471 | + "disk_read" => Ok(Self::DiskRead), |
| 472 | + "disk_write" => Ok(Self::DiskWrite), |
| 473 | + |
| 474 | + "net_down" => Ok(Self::NetDown), |
| 475 | + "net_up" => Ok(Self::NetUp), |
| 476 | + |
| 477 | + "load_average_1" => Ok(Self::LoadAverage1), |
| 478 | + "load_average_5" => Ok(Self::LoadAverage5), |
| 479 | + "load_average_15" => Ok(Self::LoadAverage15), |
| 480 | + "uptime" => Ok(Self::Uptime), |
| 481 | + _ => Err(Report::msg(format!("invalid token type: '{s}'"))), |
| 482 | + } |
| 483 | + } |
| 484 | +} |
| 485 | + |
| 486 | +impl Namespace for Client { |
| 487 | + fn get(&self, key: &str) -> Option<String> { |
| 488 | + let get = |value: Value| Some(value.get(Prefix::None).to_string()); |
| 489 | + |
| 490 | + let token = TokenType::from_str(key).ok()?; |
| 491 | + match token { |
| 492 | + TokenType::CpuFrequency => None, |
| 493 | + TokenType::CpuPercent => None, |
| 494 | + TokenType::MemoryFree => get(self.memory_free()), |
| 495 | + TokenType::MemoryAvailable => get(self.memory_available()), |
| 496 | + TokenType::MemoryTotal => get(self.memory_total()), |
| 497 | + TokenType::MemoryUsed => get(self.memory_used()), |
| 498 | + TokenType::MemoryPercent => get(self.memory_percent()), |
| 499 | + TokenType::SwapFree => get(self.swap_free()), |
| 500 | + TokenType::SwapTotal => get(self.swap_total()), |
| 501 | + TokenType::SwapUsed => get(self.swap_used()), |
| 502 | + TokenType::SwapPercent => get(self.swap_percent()), |
| 503 | + TokenType::TempC => None, |
| 504 | + TokenType::TempF => None, |
| 505 | + TokenType::DiskFree => None, |
| 506 | + TokenType::DiskTotal => None, |
| 507 | + TokenType::DiskUsed => None, |
| 508 | + TokenType::DiskPercent => None, |
| 509 | + TokenType::DiskRead => None, |
| 510 | + TokenType::DiskWrite => None, |
| 511 | + TokenType::NetDown => None, |
| 512 | + TokenType::NetUp => None, |
| 513 | + TokenType::LoadAverage1 => get(self.load_average_1()), |
| 514 | + TokenType::LoadAverage5 => get(self.load_average_5()), |
| 515 | + TokenType::LoadAverage15 => get(self.load_average_15()), |
| 516 | + TokenType::Uptime => Some(self.uptime()), |
| 517 | + } |
| 518 | + } |
| 519 | + |
| 520 | + fn list(&self) -> Vec<String> { |
| 521 | + vec![ |
| 522 | + "memory_free", |
| 523 | + "memory_available", |
| 524 | + "memory_total", |
| 525 | + "memory_used", |
| 526 | + "memory_percent", |
| 527 | + "swap_free", |
| 528 | + "swap_total", |
| 529 | + "swap_used", |
| 530 | + "swap_percent", |
| 531 | + "load_average_1", |
| 532 | + "load_average_5", |
| 533 | + "load_average_15", |
| 534 | + "uptime", |
| 535 | + ] |
| 536 | + .into_iter() |
| 537 | + .map(ToString::to_string) |
| 538 | + .collect() |
| 539 | + } |
| 540 | + |
| 541 | + fn namespaces(&self) -> Vec<String> { |
| 542 | + vec![ |
| 543 | + "cpu_frequency", |
| 544 | + "cpu_percent", |
| 545 | + "temp_c", |
| 546 | + "temp_f", |
| 547 | + "disk_free", |
| 548 | + "disk_total", |
| 549 | + "disk_used", |
| 550 | + "disk_percent", |
| 551 | + "disk_read", |
| 552 | + "disk_write", |
| 553 | + "net_down", |
| 554 | + "net_up", |
| 555 | + ] |
| 556 | + .into_iter() |
| 557 | + .map(ToString::to_string) |
| 558 | + .collect() |
| 559 | + } |
| 560 | + |
| 561 | + fn get_namespace(&self, key: &str) -> Option<Arc<dyn Namespace + Sync + Send>> { |
| 562 | + let token = TokenType::from_str(key).ok()?; |
| 563 | + |
| 564 | + match token { |
| 565 | + TokenType::CpuFrequency => Some(Arc::new(self.cpu_frequency())), |
| 566 | + TokenType::CpuPercent => Some(Arc::new(self.cpu_percent())), |
| 567 | + TokenType::MemoryFree => None, |
| 568 | + TokenType::MemoryAvailable => None, |
| 569 | + TokenType::MemoryTotal => None, |
| 570 | + TokenType::MemoryUsed => None, |
| 571 | + TokenType::MemoryPercent => None, |
| 572 | + TokenType::SwapFree => None, |
| 573 | + TokenType::SwapTotal => None, |
| 574 | + TokenType::SwapUsed => None, |
| 575 | + TokenType::SwapPercent => None, |
| 576 | + TokenType::TempC => Some(Arc::new(self.temp_c())), |
| 577 | + TokenType::TempF => Some(Arc::new(self.temp_f())), |
| 578 | + TokenType::DiskFree => Some(Arc::new(self.disk_free())), |
| 579 | + TokenType::DiskTotal => Some(Arc::new(self.disk_total())), |
| 580 | + TokenType::DiskUsed => Some(Arc::new(self.disk_used())), |
| 581 | + TokenType::DiskPercent => Some(Arc::new(self.disk_percent())), |
| 582 | + TokenType::DiskRead => Some(Arc::new(self.disk_read(Interval::All(1)))), |
| 583 | + TokenType::DiskWrite => Some(Arc::new(self.disk_write(Interval::All(1)))), |
| 584 | + TokenType::NetDown => Some(Arc::new(self.net_down(Interval::All(1)))), |
| 585 | + TokenType::NetUp => Some(Arc::new(self.net_up(Interval::All(1)))), |
| 586 | + TokenType::LoadAverage1 => None, |
| 587 | + TokenType::LoadAverage5 => None, |
| 588 | + TokenType::LoadAverage15 => None, |
| 589 | + TokenType::Uptime => None, |
| 590 | + } |
| 591 | + } |
| 592 | +} |
| 593 | + |
| 594 | +impl Namespace for ValueSet { |
| 595 | + fn get(&self, key: &str) -> Option<String> { |
| 596 | + let function = Function::from_str(key).ok()?; |
| 597 | + Some(self.apply(&function, Prefix::None).to_string()) |
| 598 | + } |
| 599 | + |
| 600 | + fn list(&self) -> Vec<String> { |
| 601 | + let mut vec = vec!["sum", "min", "max", "mean"] |
| 602 | + .into_iter() |
| 603 | + .map(ToString::to_string) |
| 604 | + .collect::<Vec<_>>(); |
| 605 | + |
| 606 | + vec.extend(self.values.keys().map(ToString::to_string)); |
| 607 | + vec |
| 608 | + } |
| 609 | + |
| 610 | + fn namespaces(&self) -> Vec<String> { |
| 611 | + vec![] |
| 612 | + } |
| 613 | + |
| 614 | + fn get_namespace(&self, _key: &str) -> Option<Arc<dyn Namespace + Sync + Send>> { |
| 615 | + None |
| 616 | + } |
| 617 | +} |
0 commit comments