homoglyph_core/
word.rs

1//! A Word reprensent a sequence of Glyph.
2
3use crate::{
4    glyph::{EncodedGlyph, Glyph},
5    Decodable, Encodable,
6};
7use std::{num::ParseIntError, slice::Iter, str::FromStr};
8
9// A word is a Vector of Glyph.
10#[derive(Debug, PartialEq, Clone)]
11pub struct Word(pub Vec<Glyph>);
12
13impl Word {
14    /// Create a new Word from a vector of Glyph.
15    pub fn new(glyphs: Vec<Glyph>) -> Self {
16        Self(glyphs)
17    }
18
19    pub fn iter(&self) -> Iter<Glyph> {
20        self.0.iter()
21    }
22
23    /// Convert a Word into a string
24    pub fn to_string(&self) -> String {
25        let mut string = String::new();
26        for glyph_dec in self.0.iter() {
27            string.push_str(glyph_dec.0.to_string().as_str());
28        }
29        string
30    }
31}
32
33impl FromStr for Word {
34    type Err = ();
35
36    fn from_str(s: &str) -> Result<Self, Self::Err> {
37        let mut word: Vec<Glyph> = Vec::new();
38
39        for c in s.chars().into_iter() {
40            word.push(Glyph::new(c));
41        }
42
43        Ok(Word::new(word))
44    }
45}
46
47/// A Word can be encoded into Unicode code.
48impl Encodable<EncodedWord> for Word {
49    fn encode(&self) -> Result<EncodedWord, ParseIntError> {
50        let vec: Vec<EncodedGlyph> = self
51            .0
52            .iter()
53            .map(|unencoded_g| unencoded_g.encode().unwrap())
54            .collect();
55        Ok(EncodedWord::new(vec))
56    }
57}
58
59/// A unicode encoded Word.
60#[derive(Debug, PartialEq, Clone)]
61pub struct EncodedWord(pub Vec<EncodedGlyph>);
62
63impl EncodedWord {
64    /// Create a new EncodedWord from a Vector of EncodedGlyph.
65    pub fn new(encoded_glyphs: Vec<EncodedGlyph>) -> Self {
66        EncodedWord(encoded_glyphs)
67    }
68
69    /// Convert an EncodedWord into a string.
70    pub fn to_string(&self) -> String {
71        let mut string = String::new();
72        for glyph_enc in self.0.iter() {
73            string.push_str(glyph_enc.0.as_str())
74        }
75        string
76    }
77
78    pub fn iter(&self) -> Iter<EncodedGlyph> {
79        self.0.iter()
80    }
81}
82
83impl From<&str> for EncodedWord {
84    fn from(s: &str) -> Self {
85        let mut word: Vec<EncodedGlyph> = Vec::new();
86        for c in s.chars().into_iter() {
87            word.push(EncodedGlyph::from(c));
88        }
89
90        EncodedWord::new(word)
91    }
92}
93
94impl From<EncodedWord> for String {
95    fn from(word_enc: EncodedWord) -> Self {
96        let mut string = String::new();
97        for glyph_enc in word_enc.0.iter() {
98            string.push_str(glyph_enc.0.as_str())
99        }
100        string
101    }
102}
103
104impl FromStr for EncodedWord {
105    type Err = ();
106
107    //TODO: Only take already encoded str
108    fn from_str(s: &str) -> Result<Self, Self::Err> {
109        //TODO: Check of encoded_str
110        let mut word: Vec<EncodedGlyph> = Vec::new();
111        for c in s.chars().into_iter() {
112            word.push(EncodedGlyph::from(c));
113        }
114
115        Ok(EncodedWord::new(word))
116    }
117}
118
119/// An EncodedWord can be decoded from an EncodedWord.
120impl Decodable<Word> for EncodedWord {
121    fn decode(&self) -> Result<Word, ParseIntError> {
122        let decoded_word = self.0.iter().map(|enc_g| enc_g.decode().unwrap()).collect();
123        Ok(Word::new(decoded_word))
124    }
125}
126
127#[cfg(test)]
128mod tests {
129    use super::*;
130
131    #[test]
132    fn given_decoded_word_then_encoded_when_decoded_again_should_be_equal() {
133        let w = Word::from_str("rust").unwrap();
134        let w_enc = w.encode().unwrap();
135        let w_dec = w_enc.decode().unwrap();
136        assert_eq!(w_dec, w);
137    }
138}