use std::path::{PathBuf,Path};
use serde::{Serialize, Deserialize};
use local_ip_address::local_ip;
use std::fmt;
use std::default::Default;
use chrono::{DateTime,Utc};
use moebius_tools::time::has_dt_gen::HasDtGen;
use super::dt_gen_format;
#[derive(Debug,Serialize,Deserialize,Clone)]
pub enum Scala {
Bytes,
KiloBytes,
MegaBytes,
GigaBytes,
TeraBytes
}
impl Scala {
pub fn value(&self)->f64 {
match self {
Self::Bytes => 1_f64,
Self::KiloBytes => 1024_f64,
Self::MegaBytes => u64::pow(1024,2) as f64,
Self::GigaBytes => u64::pow(1024,3) as f64,
Self::TeraBytes => u64::pow(1024,4) as f64,
}
}
}
impl Default for Scala {
fn default() -> Self { Self::GigaBytes }
}
impl fmt::Display for Scala {
fn fmt(&self, f:&mut fmt::Formatter) -> fmt::Result {
match self {
Self::Bytes => write!(f,"Bytes"),
Self::KiloBytes => write!(f,"Kb"),
Self::MegaBytes => write!(f,"Mb"),
Self::GigaBytes => write!(f,"Gb"),
Self::TeraBytes => write!(f,"Tb"),
}
}
}
#[derive(Debug,Serialize,Deserialize,Clone)]
pub struct Memory {
available:u64,
free:u64,
total:u64
}
impl Memory {
pub fn new(path: &Path) -> Self {
if path.exists(){
Self {
available:fs2::available_space(path).unwrap(),
free:fs2::free_space(path).unwrap(),
total:fs2::total_space(path).unwrap()
}
} else{
Self {
available:0,
free:0,
total:0
}
}
}
pub fn get_free(&self) -> u64 {
self.free
}
pub fn get_total(&self) -> u64 {
self.total
}
pub fn get_available(&self) -> u64 {
self.available
}
pub fn json(&self) -> String {
serde_json::to_string(self).unwrap()
}
pub fn from_json(serialized:&str) -> Self {
serde_json::from_str(serialized).unwrap()
}
pub fn human(&self, scala:&Scala) -> MemoryHumanInfo {
MemoryHumanInfo {
available:(self.available as f64)/scala.value(),
percentage:(self.available as f64)/(self.total as f64)*100.0,
scala:scala.clone(),
}
}
}
impl fmt::Display for Memory {
fn fmt(&self, f:&mut fmt::Formatter) -> fmt::Result {
write!(f,"Memory: available:{} Bytes - free:{} bytes - total: {} Bytes",self.available,self.free, self.total)
}
}
#[derive(Debug,Serialize,Deserialize)]
pub struct MemoryHumanInfo {
available: f64,
percentage: f64,
scala:Scala
}
impl MemoryHumanInfo {
pub fn json(&self) -> String {
serde_json::to_string(self).unwrap()
}
pub fn from_json(serialized:&str) -> Self {
serde_json::from_str(serialized).unwrap()
}
pub fn get_percentage(&self) -> f64 {
self.percentage
}
pub fn get_scala(&self) -> Scala {
self.scala.clone()
}
pub fn get_available(&self) -> f64 {
self.available
}
}
impl fmt::Display for MemoryHumanInfo {
fn fmt(&self, f:&mut fmt::Formatter) -> fmt::Result {
write!(f,"Memory: {:.3} [{}]: {:.3} [%]",self.available,self.scala,self.percentage)
}
}
#[derive(Debug,Serialize,Deserialize)]
pub struct Device {
id:u32,
name:String,
host:String,
db_path: PathBuf,
memory:Memory,
#[serde(with = "dt_gen_format")] datetime:DateTime<Utc>
}
impl HasDtGen for Device {
fn get_dt_gen(&self) -> DateTime<Utc> {
self.datetime
}
}
impl Device {
pub fn new(id:u32, name:&str, db_path:&Path) -> Self {
let host = local_ip().unwrap().to_string();
Self {
id,
name:name.into(),
host,
db_path:db_path.into(),
memory:Memory::new(db_path),
datetime:Utc::now()
}
}
pub fn json(&self) -> String {
serde_json::to_string(self).unwrap()
}
pub fn from_json(serialized:&str) -> Self {
serde_json::from_str(serialized).unwrap()
}
pub fn memory_info(&self)->MemoryHumanInfo{
let scala = Scala::default();
self.memory.human(&scala)
}
pub fn get_memory(&self) -> Memory {
self.memory.clone()
}
pub fn get_id(&self) -> u32{
self.id
}
pub fn get_datetime(&self) -> DateTime<Utc>{
self.datetime
}
pub fn get_name(&self) -> String{
self.name.clone()
}
pub fn get_host(&self) -> String{
self.host.clone()
}
pub fn get_db_path(&self) -> PathBuf{
self.db_path.clone()
}
}
impl fmt::Display for Device {
fn fmt(&self, f:&mut fmt::Formatter) -> fmt::Result {
write!(f,"Device:\nid:{}\nname:{}\nhost:{}\ndatetime:{}\ndb:{:?}\n{}",
self.id,
self.name,
self.host,
self.datetime,
self.db_path,
self.memory)
}
}