libnsave/
common.rs

1use crate::configure::*;
2use chrono::{DateTime, Datelike, Local, NaiveDateTime, TimeZone, Timelike};
3use libc::timeval;
4use std::convert::From;
5use std::io;
6use std::path::PathBuf;
7use std::time::{SystemTime, UNIX_EPOCH};
8
9pub const VERSION: &str = "0.1";
10pub const AUTHOR: &str = "LiChunhui <chunhui_true@163.com>";
11pub const DEFAULT_CONFIG_FILE: &str = ".nsave_conf.toml";
12
13#[derive(Debug)]
14pub enum StoreError {
15    IoError(std::io::Error),
16    InitError(String),
17    FormatError(String),
18    ReadError(String),
19    WriteError(String),
20    CliError(String),
21    LockError(String),
22    OpenError(String),
23}
24
25impl std::fmt::Display for StoreError {
26    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27        match self {
28            StoreError::IoError(err) => write!(f, "IO error: {}", err),
29            StoreError::InitError(msg) => write!(f, "Init error: {}", msg),
30            StoreError::FormatError(msg) => write!(f, "Format error: {}", msg),
31            StoreError::ReadError(msg) => write!(f, "Read error: {}", msg),
32            StoreError::WriteError(msg) => write!(f, "Write error: {}", msg),
33            StoreError::CliError(msg) => write!(f, "Write error: {}", msg),
34            StoreError::LockError(msg) => write!(f, "lock error: {}", msg),
35            StoreError::OpenError(msg) => write!(f, "open error: {}", msg),
36        }
37    }
38}
39
40impl std::error::Error for StoreError {}
41
42impl From<std::io::Error> for StoreError {
43    fn from(err: std::io::Error) -> Self {
44        StoreError::IoError(err)
45    }
46}
47
48impl From<String> for StoreError {
49    fn from(err: String) -> Self {
50        StoreError::InitError(err)
51    }
52}
53
54impl From<StoreError> for io::Error {
55    fn from(error: StoreError) -> io::Error {
56        io::Error::new(io::ErrorKind::Other, error)
57    }
58}
59
60#[derive(Debug)]
61pub enum Msg {
62    CoverChunk(PathBuf, u128),
63}
64
65pub fn ts_date(timestamp: u128) -> DateTime<Local> {
66    let naive_datetime = DateTime::from_timestamp(
67        (timestamp / 1_000_000_000).try_into().unwrap(),
68        (timestamp % 1_000_000_000) as u32,
69    );
70    Local.from_utc_datetime(
71        &naive_datetime
72            .expect("Failed to convert to local time")
73            .naive_utc(),
74    )
75}
76
77pub fn date_ts(time: Option<NaiveDateTime>) -> Option<u128> {
78    time.map(|t| {
79        let datetime_local: DateTime<Local> = Local.from_local_datetime(&t).unwrap();
80        datetime_local.timestamp_nanos_opt().map(|ts| ts as u128)
81    })?
82}
83
84pub fn ts_timeval(timestamp: u128) -> timeval {
85    let seconds = (timestamp / 1_000_000_000) as i64;
86    let nanoseconds = (timestamp % 1_000_000_000) as i64;
87    timeval {
88        tv_sec: seconds,
89        tv_usec: (nanoseconds * 1000) as _,
90    }
91}
92
93pub fn timenow() -> u128 {
94    SystemTime::now()
95        .duration_since(UNIX_EPOCH)
96        .unwrap()
97        .as_nanos()
98}
99
100pub fn date2dir(configure: &'static Configure, dir_id: u64, date: NaiveDateTime) -> PathBuf {
101    let mut path = PathBuf::new();
102    path.push(configure.store_path.clone());
103    path.push(format!("{:03}", dir_id));
104    path.push(format!("{:04}", date.year()));
105    path.push(format!("{:02}", date.month()));
106    path.push(format!("{:02}", date.day()));
107    path.push(format!("{:02}", date.hour()));
108    path.push(format!("{:02}", date.minute()));
109    path
110}