gistit_project/
lib.rs

1//
2//   ________.__          __  .__  __
3//  /  _____/|__| _______/  |_|__|/  |_
4// /   \  ___|  |/  ___/\   __\  \   __\
5// \    \_\  \  |\___ \  |  | |  ||  |
6//  \______  /__/____  > |__| |__||__|
7//         \/        \/
8//
9#![warn(clippy::all, clippy::pedantic, clippy::nursery, clippy::cargo)]
10#![cfg_attr(
11    test,
12    allow(
13        unused,
14        clippy::all,
15        clippy::pedantic,
16        clippy::nursery,
17        clippy::dbg_macro,
18        clippy::unwrap_used,
19        clippy::missing_docs_in_private_items,
20    )
21)]
22
23pub const APPLICATION: &str = "Gistit";
24
25pub const ORGANIZATION: &str = "demfabris";
26
27pub const QUALIFIER: &str = "io";
28
29pub mod path {
30    use std::fs;
31    use std::path::{Path, PathBuf};
32
33    use directories::{BaseDirs, ProjectDirs};
34
35    use super::{env, Error, Result};
36
37    use super::{APPLICATION, ORGANIZATION, QUALIFIER};
38
39    /// Initialize needed project directories if not present
40    ///
41    /// # Errors
42    ///
43    /// Fails if can't create folder in home config directory
44    pub fn init() -> Result<()> {
45        let config = config()?;
46        if fs::metadata(&config).is_err() {
47            fs::create_dir_all(&config)?;
48        }
49
50        let runtime = runtime()?;
51        if fs::metadata(&runtime).is_err() {
52            fs::create_dir_all(&runtime)?;
53        }
54
55        let data = data()?;
56        if fs::metadata(&data).is_err() {
57            fs::create_dir_all(&data)?;
58        }
59
60        Ok(())
61    }
62
63    /// Returns the runtime path of this program
64    /// Fallbacks to a temporary folder
65    ///
66    /// # Errors
67    ///
68    /// Fails if the system doesn't have a HOME directory
69    pub fn runtime() -> Result<PathBuf> {
70        let default = BaseDirs::new()
71            .ok_or(Error::Directory("can't open home directory"))?
72            .runtime_dir()
73            .map_or_else(std::env::temp_dir, Path::to_path_buf);
74        Ok(env::var_or_default(env::GISTIT_RUNTIME_VAR, default))
75    }
76
77    /// Returns the config path of this program
78    ///
79    /// # Errors
80    ///
81    /// Fails if the system doesn't have a HOME directory
82    pub fn config() -> Result<PathBuf> {
83        let default = ProjectDirs::from(QUALIFIER, ORGANIZATION, APPLICATION)
84            .ok_or(Error::Directory("can't open home directory"))?
85            .config_dir()
86            .to_path_buf();
87        Ok(env::var_or_default(env::GISTIT_CONFIG_VAR, default))
88    }
89
90    /// Returns the data path of this program
91    ///
92    /// # Errors
93    ///
94    /// Fails if the system doesn't have a HOME directory
95    pub fn data() -> Result<PathBuf> {
96        let default = ProjectDirs::from(QUALIFIER, ORGANIZATION, APPLICATION)
97            .ok_or(Error::Directory("can't open home directory"))?
98            .data_dir()
99            .to_path_buf();
100        Ok(env::var_or_default(env::GISTIT_DATA_VAR, default))
101    }
102}
103
104pub mod env {
105    use std::env;
106    use std::path::{Path, PathBuf};
107
108    pub const GISTIT_RUNTIME_VAR: &str = "GISTIT_RUNTIME";
109
110    pub const GISTIT_CONFIG_VAR: &str = "GISTIT_CONFIG";
111
112    pub const GISTIT_DATA_VAR: &str = "GISTIT_DATA";
113
114    pub const GISTIT_SERVER_URL: &str = "GISTIT_SERVER_URL";
115
116    #[must_use]
117    pub fn var_or_default(var: &str, default: PathBuf) -> PathBuf {
118        env::var_os(var)
119            .as_ref()
120            .map_or(default, |t| Path::new(t).to_path_buf())
121    }
122}
123
124pub mod var {
125    /// Max gistit size allowed in bytes
126    pub const GISTIT_MAX_SIZE: usize = 50_000;
127
128    /// Gistit hash size (sha256)
129    pub const GISTIT_HASH_LENGTH: usize = 64;
130
131    /// Default server base url
132    pub const GISTIT_SERVER_URL_BASE: &str = "https://us-central1-gistit-base.cloudfunctions.net/";
133}
134
135pub type Result<T> = std::result::Result<T, Error>;
136
137#[derive(thiserror::Error, Debug)]
138pub enum Error {
139    #[error("project directory error: {0}")]
140    Directory(&'static str),
141
142    #[error("io error: {0}")]
143    IO(#[from] std::io::Error),
144}