notebook_rs/
lib.rs

1use crate::notebook::Notebook;
2
3use entry::Entry;
4use serde::{Deserialize, Serialize};
5use std::{env, fmt, fs, io, io::prelude::*, process::Command};
6
7pub mod argparse;
8pub mod config;
9pub mod entry;
10pub mod notebook;
11
12#[derive(Clone, Debug)]
13pub enum Args {
14    New(Entry),
15    List(usize, u8),
16    Read(usize),
17    Edit(usize),
18    Delete(usize, bool),
19    Search(String),
20    DateFilter(String),
21    DateSearch(String),
22    Unimplemented(),
23}
24
25#[derive(Clone, Debug)]
26struct Sentiment {
27    compound: f64,
28    icon: String,
29}
30
31impl Sentiment {
32    fn new(compound: f64) -> Sentiment {
33        let icon = match compound {
34            c if c <= -0.7 => "😿",
35            c if c <= -0.2 => "😾",
36            c if c <= 0.2 => "🐱",
37            c if c <= 0.7 => "😺",
38            c if c <= 1.0 => "😸",
39            _ => "Problemo",
40        };
41
42        Sentiment {
43            compound,
44            icon: icon.to_owned(),
45        }
46    }
47}
48
49impl fmt::Display for Sentiment {
50    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51        write!(f, "{:.3} ≅ {}", self.compound, self.icon)
52    }
53}
54
55#[derive(Clone, Debug, Serialize, Deserialize)]
56struct EncryptionScheme {
57    cipher: bool,
58    hash: bool,
59    salt: bool,
60}
61
62fn get_user_confirm<R>(mut reader: R, prompt: String) -> bool
63where
64    R: io::BufRead,
65{
66    print!("{prompt} (Y/n) ");
67    let _ = io::stdout().flush();
68    let mut buffer = String::new();
69
70    reader.read_line(&mut buffer).expect("Error reading input.");
71
72    buffer.starts_with('Y')
73}
74
75pub fn create_temp_file(filename: Option<&str>) -> String {
76    let mut file_path = env::temp_dir();
77    file_path.push(filename.unwrap_or("notebook_rs"));
78    fs::File::create(&file_path).expect("Could not create file.");
79    file_path.into_os_string().into_string().unwrap()
80}
81
82pub fn text_from_editor(path: Option<String>) -> Option<String> {
83    let editor = env::var("EDITOR").expect("EDITOR environment variable is missing.");
84    let file_path = path.unwrap_or_else(|| create_temp_file(None));
85
86    Command::new(editor)
87        .arg(&file_path)
88        .status()
89        .expect("Something went wrong with the editor.");
90
91    let mut text = String::new();
92    fs::File::open(&file_path)
93        .expect("Couldn't open temp file.")
94        .read_to_string(&mut text)
95        .expect("Couldn't load file to string.");
96
97    fs::remove_file(file_path).expect("Couldn't remove temp file.");
98
99    if text.is_empty() {
100        None
101    } else {
102        Some(text)
103    }
104}
105
106#[cfg(test)]
107mod test_util {
108    use super::*;
109
110    #[test]
111    fn test_missing_editor_variable() {
112        env::remove_var("EDITOR");
113        let result = std::panic::catch_unwind(|| text_from_editor(None));
114        assert!(result.is_err());
115    }
116
117    #[test]
118    fn test_user_confirm_pos() {
119        let pos = b"Y";
120        assert!(get_user_confirm(&pos[..], "Prompt".to_string()))
121    }
122
123    #[test]
124    fn test_user_confirm_neg() {
125        let pos = b"n";
126        assert_eq!(get_user_confirm(&pos[..], "Prompt".to_string()), false)
127    }
128}