translate/
lib.rs

1#![doc = include_str!("../README.md")]
2#![deny(missing_docs)]
3
4mod parsing;
5
6/// Represents a token of a paragraph/page.
7pub enum Token {
8    /// A separator symbol.
9    Separator(char),
10    /// A word.
11    Word(String),
12}
13
14impl Token {
15    /// Tokenize a text.
16    pub fn tokenize(text: &str) -> Vec<Token> {
17        let mut word = String::new();
18        let mut res = vec![];
19        for ch in text.chars() {
20            match ch {
21                '\n' | ' ' | '.' | ',' | ':' | ';' |
22                '[' | ']' | '(' | ')' |
23                '“' | '"' | '”' | '’' |
24                '—' => {
25                    if word.len() > 0 {
26                        res.push(Token::Word(word));
27                        word = String::new();
28                    }
29                    res.push(Token::Separator(ch));
30                }
31                _ => word.push(ch),
32            }
33        }
34
35
36        if word.len() > 0 {
37            res.push(Token::Word(word));
38        }
39
40        res
41    }
42}
43
44/// Defines the data structure of Translate documents.
45pub type Data = Vec<(String, String)>;
46
47/// Create empty data document.
48///
49/// This contains one item by default.
50pub fn new() -> Data {
51    vec![("".into(), "".into())]
52}
53
54/// Save data to file.
55pub fn save(file: &str, data: &Data) -> Result<(), std::io::Error> {
56    use std::fs::File;
57    use std::io::Write;
58
59    let mut file = File::create(file)?;
60    writeln!(file, "[")?;
61    let mut first = true;
62    for (from, to) in data {
63        if first {
64            first = false;
65        } else {
66            writeln!(file, ",")?;
67        }
68        write!(file, "  [\n    {:?},\n    {:?}\n  ]", from, to)?;
69    }
70    writeln!(file, "\n]")?;
71    Ok(())
72}
73
74/// Load data from file.
75pub fn load(file: &str) -> Result<Data, String> {
76    use std::fs::File;
77    use std::io::Read;
78
79    let mut file = File::open(file).map_err(|_|
80        "Could not open file".to_string())?;
81    let mut bytes = vec![];
82    file.read_to_end(&mut bytes).unwrap();
83    let source = String::from_utf8(bytes)
84        .map_err(|_| "Could not convert to UTF8 text".to_string())?;
85    parsing::parse_str(&source)
86}
87
88#[cfg(test)]
89mod tests {
90    use super::*;
91
92    #[test]
93    fn it_works() {
94        let a = parsing::parse_str(r#"[["a", "b"]]"#).unwrap();
95        assert_eq!(a, vec![("a".to_string(), "b".to_string())]);
96
97        let a = parsing::parse_str(r#"[["a", "b"], ["c", "d"]]"#).unwrap();
98        assert_eq!(a, vec![
99            ("a".to_string(), "b".to_string()),
100            ("c".to_string(), "d".to_string()),
101        ]);
102    }
103}