leetcode_cli/config/
mod.rs

1//! Soft-link with `config.toml`
2//!
3//! leetcode-cli will generate a `leetcode.toml` by default,
4//! if you wanna change to it, you can:
5//!
6//! + Edit leetcode.toml at `~/.leetcode/leetcode.toml` directly
7//! + Use `leetcode config` to update it
8use crate::{
9    config::{code::Code, cookies::Cookies, storage::Storage, sys::Sys},
10    Error, Result,
11};
12use serde::{Deserialize, Serialize};
13use std::{fs, path::Path};
14
15mod code;
16mod cookies;
17mod storage;
18mod sys;
19
20pub use cookies::LeetcodeSite;
21
22/// Sync with `~/.leetcode/leetcode.toml`
23#[derive(Clone, Debug, Default, Deserialize, Serialize)]
24pub struct Config {
25    #[serde(default, skip_serializing)]
26    pub sys: Sys,
27    pub code: Code,
28    pub cookies: Cookies,
29    pub storage: Storage,
30}
31
32impl Config {
33    fn write_default(p: impl AsRef<Path>) -> Result<()> {
34        fs::write(p.as_ref(), toml::ser::to_string_pretty(&Self::default())?)?;
35
36        Ok(())
37    }
38
39    /// Locate lc's config file
40    pub fn locate() -> Result<Config> {
41        let conf = Self::root()?.join("leetcode.toml");
42
43        if !conf.is_file() {
44            Self::write_default(&conf)?;
45        }
46
47        let s = fs::read_to_string(&conf)?;
48        match toml::from_str::<Config>(&s) {
49            Ok(config) => match config.cookies.site {
50                cookies::LeetcodeSite::LeetcodeCom => Ok(config),
51                cookies::LeetcodeSite::LeetcodeCn => {
52                    let mut config = config;
53                    config.sys.urls = sys::Urls::new_with_leetcode_cn();
54                    Ok(config)
55                }
56            },
57            Err(e) => {
58                let tmp = Self::root()?.join("leetcode.tmp.toml");
59                Self::write_default(tmp)?;
60                Err(e.into())
61            }
62        }
63    }
64
65    /// Get root path of leetcode-cli
66    pub fn root() -> Result<std::path::PathBuf> {
67        let dir = dirs::home_dir().ok_or(Error::NoneError)?.join(".leetcode");
68        if !dir.is_dir() {
69            info!("Generate root dir at {:?}.", &dir);
70            fs::DirBuilder::new().recursive(true).create(&dir)?;
71        }
72
73        Ok(dir)
74    }
75
76    /// Sync new config to config.toml
77    pub fn sync(&self) -> Result<()> {
78        let home = dirs::home_dir().ok_or(Error::NoneError)?;
79        let conf = home.join(".leetcode/leetcode.toml");
80        fs::write(conf, toml::ser::to_string_pretty(&self)?)?;
81
82        Ok(())
83    }
84}