nsave 0.1.0

capturing and saving packets
Documentation
use crate::configure::*;
use chrono::{DateTime, Datelike, Local, NaiveDateTime, TimeZone, Timelike};
use libc::timeval;
use std::convert::From;
use std::io;
use std::path::PathBuf;
use std::time::{SystemTime, UNIX_EPOCH};

pub const VERSION: &str = "0.1";
pub const AUTHOR: &str = "LiChunhui <chunhui_true@163.com>";
pub const DEFAULT_CONFIG_FILE: &str = ".nsave_conf.toml";

#[derive(Debug)]
pub enum StoreError {
    IoError(std::io::Error),
    InitError(String),
    FormatError(String),
    ReadError(String),
    WriteError(String),
    CliError(String),
    LockError(String),
    OpenError(String),
}

impl std::fmt::Display for StoreError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            StoreError::IoError(err) => write!(f, "IO error: {}", err),
            StoreError::InitError(msg) => write!(f, "Init error: {}", msg),
            StoreError::FormatError(msg) => write!(f, "Format error: {}", msg),
            StoreError::ReadError(msg) => write!(f, "Read error: {}", msg),
            StoreError::WriteError(msg) => write!(f, "Write error: {}", msg),
            StoreError::CliError(msg) => write!(f, "Write error: {}", msg),
            StoreError::LockError(msg) => write!(f, "lock error: {}", msg),
            StoreError::OpenError(msg) => write!(f, "open error: {}", msg),
        }
    }
}

impl std::error::Error for StoreError {}

impl From<std::io::Error> for StoreError {
    fn from(err: std::io::Error) -> Self {
        StoreError::IoError(err)
    }
}

impl From<String> for StoreError {
    fn from(err: String) -> Self {
        StoreError::InitError(err)
    }
}

impl From<StoreError> for io::Error {
    fn from(error: StoreError) -> io::Error {
        io::Error::new(io::ErrorKind::Other, error)
    }
}

#[derive(Debug)]
pub enum Msg {
    CoverChunk(PathBuf, u128),
}

pub fn ts_date(timestamp: u128) -> DateTime<Local> {
    let naive_datetime = DateTime::from_timestamp(
        (timestamp / 1_000_000_000).try_into().unwrap(),
        (timestamp % 1_000_000_000) as u32,
    );
    Local.from_utc_datetime(
        &naive_datetime
            .expect("Failed to convert to local time")
            .naive_utc(),
    )
}

pub fn date_ts(time: Option<NaiveDateTime>) -> Option<u128> {
    time.map(|t| {
        let datetime_local: DateTime<Local> = Local.from_local_datetime(&t).unwrap();
        datetime_local.timestamp_nanos_opt().map(|ts| ts as u128)
    })?
}

pub fn ts_timeval(timestamp: u128) -> timeval {
    let seconds = (timestamp / 1_000_000_000) as i64;
    let nanoseconds = (timestamp % 1_000_000_000) as i64;
    timeval {
        tv_sec: seconds,
        tv_usec: (nanoseconds * 1000) as _,
    }
}

pub fn timenow() -> u128 {
    SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_nanos()
}

pub fn date2dir(configure: &'static Configure, dir_id: u64, date: NaiveDateTime) -> PathBuf {
    let mut path = PathBuf::new();
    path.push(configure.store_path.clone());
    path.push(format!("{:03}", dir_id));
    path.push(format!("{:04}", date.year()));
    path.push(format!("{:02}", date.month()));
    path.push(format!("{:02}", date.day()));
    path.push(format!("{:02}", date.hour()));
    path.push(format!("{:02}", date.minute()));
    path
}