kidex_common/
lib.rs

1use std::path::PathBuf;
2
3use serde::{Deserialize, Serialize};
4
5pub const DEFAULT_SOCKET: &str = "/tmp/kidex.sock";
6
7#[derive(Deserialize, Serialize)]
8pub enum IpcCommand {
9    FullIndex,
10    Quit,
11    Reload,
12    GetIndex(Option<PathBuf>),
13}
14
15#[derive(Deserialize, Serialize)]
16pub enum IpcResponse {
17    Success,
18    NotFound,
19    Index(Vec<IndexEntry>),
20}
21
22#[derive(Deserialize, Serialize, Clone)]
23pub struct IndexEntry {
24    pub path: PathBuf,
25    pub directory: bool,
26}
27
28#[cfg(feature = "util")]
29pub mod util {
30    use std::{
31        env,
32        fmt::Display,
33        io::{self, Read, Write},
34        os::unix::net::UnixStream,
35        path::PathBuf,
36    };
37
38    use super::{IndexEntry, IpcCommand, IpcResponse, DEFAULT_SOCKET};
39
40    #[derive(Debug)]
41    pub enum Error {
42        Io(io::Error),
43        Serde(serde_json::Error),
44        NotFound,
45        Unknown,
46    }
47
48    impl From<io::Error> for Error {
49        fn from(value: io::Error) -> Self {
50            Self::Io(value)
51        }
52    }
53
54    impl From<serde_json::Error> for Error {
55        fn from(value: serde_json::Error) -> Self {
56            Self::Serde(value)
57        }
58    }
59
60    impl Display for Error {
61        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62            match self {
63                Error::Io(why) => write!(f, "An IO error occurred: {}", why),
64                Error::Serde(why) => write!(f, "A se/deserialization error occurred: {}", why),
65                Error::NotFound => write!(f, "Requested path not found"),
66                Error::Unknown => write!(f, "An unknown error occurred"),
67            }
68        }
69    }
70
71    impl std::error::Error for Error {}
72
73    fn fetch(command: &IpcCommand) -> Result<IpcResponse, Error> {
74        let mut stream =
75            UnixStream::connect(env::var("SOCKET_PATH").unwrap_or(DEFAULT_SOCKET.to_string()))?;
76
77        let mut buf = serde_json::to_vec(command).unwrap();
78        buf.push(0x0);
79
80        stream.write_all(&buf)?;
81
82        buf.clear();
83
84        stream.read_to_end(&mut buf)?;
85
86        Ok(serde_json::from_slice(&buf)?)
87    }
88
89    pub fn get_index(path: Option<PathBuf>) -> Result<Vec<IndexEntry>, Error> {
90        match fetch(&IpcCommand::GetIndex(path))? {
91            IpcResponse::Index(index) => Ok(index),
92            IpcResponse::NotFound => Err(Error::NotFound),
93            _ => unreachable!(),
94        }
95    }
96
97    pub fn regenerate_index() -> Result<(), Error> {
98        match fetch(&IpcCommand::FullIndex)? {
99            IpcResponse::Success => Ok(()),
100            _ => Err(Error::Unknown),
101        }
102    }
103
104    pub fn shutdown_server() -> Result<(), Error> {
105        match fetch(&IpcCommand::Quit)? {
106            IpcResponse::Success => Ok(()),
107            _ => Err(Error::Unknown),
108        }
109    }
110
111    pub fn reload_config() -> Result<(), Error> {
112        match fetch(&IpcCommand::Reload)? {
113            IpcResponse::Success => Ok(()),
114            _ => Err(Error::Unknown),
115        }
116    }
117}