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}