1use std::{fs, path::{Path, PathBuf}};
2use derive_builder as builder;
3use crate::*;
4
5pub const NOTES_DIR_NAME: &'static str = "notes";
6
7const EDITOR_CMD: &'static str ="$EDITOR";
8
9#[derive(Debug, builder::Builder, Clone, serde::Serialize, serde::Deserialize)]
10pub struct NoteConfig {
11 notes_dir: PathBuf,
13 editor: String
14}
15
16#[derive(Default, Debug, Clone, serde::Serialize, serde::Deserialize, builder::Builder)]
17#[builder(default)]
18pub struct NoteConfigInput {
19 notes_dir: Option<PathBuf>,
21 editor: Option<String>
23}
24
25impl NoteConfigInput {
26 pub fn builder() -> NoteConfigInputBuilder {
27 NoteConfigInputBuilder::default()
28 }
29
30 pub fn from_toml(file: &Path) -> Result<Self> {
31 let content = fs::read_to_string(file)
32 .map_err(|e| Error::Io(format!("Unable to read SourceTrait Note config file: {}", file.display()), e))?;
33
34 toml::from_str(&content)
35 .map_err(|e| Error::ParseToml(format!("Failed to parse SourceTrait Note config file: {}", file.display()), e))
36 }
37}
38
39impl NoteConfig {
40 pub fn builder() -> NoteConfigBuilder {
41 NoteConfigBuilder::create_empty()
42 }
43
44 pub fn from_input(
45 input: NoteConfigInput,
46 user_documents_dir: PathBuf
47 ) -> Self
48 {
49 Self {
50 notes_dir: input.notes_dir
51 .unwrap_or_else(|| user_documents_dir.join(NOTES_DIR_NAME)),
52 editor: input.editor
53 .unwrap_or_else(|| EDITOR_CMD.to_string()),
54 }
55 }
56
57 pub fn to_toml_file(&self, file: &Path) -> Result<()> {
58 let content = toml::to_string(&self).expect("self valid");
59 fs::write(file, content)
60 .map_err(|e| Error::Io(format!("Unable to write to SourceTrait Note config file: {}", file.display()), e))?;
61
62 Ok(())
63 }
64
65 pub fn to_toml(&self) -> Result<String> {
66 let content = toml::to_string(&self).expect("self valid");
67 Ok(content)
68 }
69
70 pub fn notes_dir(&self) -> &Path {
71 &self.notes_dir
72 }
73
74 pub fn editor(&self) -> &str {
75 &self.editor
76 }
77}