text_converter/
lib.rs

1use arboard::Clipboard;
2use std::{
3    fs::{self, File},
4    io::Write,
5    path::Path,
6};
7
8/// Trait with all methods needed to convert text into a specific format
9pub trait TextConverter {
10    /// Transforms the input into the desired form
11    ///
12    /// Preferably never called directly, but through the other trait methods
13    ///
14    /// # Examples
15    ///
16    /// ```
17    /// struct ReverseText;
18    ///
19    /// impl TextConverter for ReverseText {
20    ///     fn converter(input: impl AsRef<str>) -> String {
21    ///         input.as_ref().chars().rev().collect()
22    ///     }
23    /// }
24    ///
25    /// let text = "Hello World!";
26    /// let reverse_text = ReverseText::new_from_text(text);
27    /// assert_eq!("!dlroW olleH", reverse_text);
28    /// ```
29    fn converter(input: impl AsRef<str>) -> String;
30
31    /// Converts given input with the [converter](Self::converter()) method
32    fn new_from_text(input: impl AsRef<str>) -> String {
33        Self::converter(input)
34    }
35
36    /// Fetches clipboard contents and converts them with the [converter](Self::converter()) method
37    /// 
38    /// # Returns
39    /// Returns the converted text from the clipboard
40    /// 
41    /// Will return an empty string if it fails to fetch the clipboard contents or if it contains something other than text
42    /// 
43    /// # Panics
44    /// Will panic if it fails to fetch the clipboard
45    fn new_from_clipboard() -> String {
46        let mut clipboard = Clipboard::new().expect("Could not fetch the clipboard contents");
47        let input = clipboard.get_text().unwrap_or_default();
48
49        Self::converter(input)
50    }
51
52    /// Fetches file contents and converts them with the [converter](Self::converter()) method
53    ///
54    /// # Panics
55    /// - If file is inaccessible or if it is not in text format (.txt, .md...)
56    /// - If it fails to create the output file
57    ///
58    /// # Returns
59    /// - The conversion string from the file contents
60    /// - Outputs the conversion into a file called originalname_converted.md
61    fn new_from_file(path: impl AsRef<Path>) -> String {
62        let input = fs::read_to_string(path.as_ref()).expect("Failed to read file contents");
63        let output = Self::converter(input);
64        let new_path = path
65            .as_ref()
66            .to_str()
67            .unwrap()
68            .split('.')
69            .take(1)
70            .collect::<String>()
71            + "_converted.md";
72
73        File::create(new_path)
74            .expect("Failed to create the output file")
75            .write_all(output.as_bytes())
76            .expect("Failed to write to the output file");
77
78        output
79    }
80}
81
82#[cfg(test)]
83mod tests {
84    use super::*;
85
86    struct ReverseText;
87
88    impl TextConverter for ReverseText {
89        fn converter(input: impl AsRef<str>) -> String {
90            input.as_ref().chars().rev().collect()
91        }
92    }
93
94    #[test]
95    fn reverse_conversion() {
96        let text = "Hello World!";
97        let reverse_text = ReverseText::new_from_text(text);
98        assert_eq!("!dlroW olleH", reverse_text);
99    }
100}