morse_lib/morse/
international.rs1use std::{cell::RefCell, ops::Index};
2
3use crate::{
4 display_chars::DisplayChars, MorseChar, MorseResult, MorseUnit,
5};
6
7#[cfg(feature = "audio")]
8use crate::sound::Sound;
9#[cfg(feature = "audio")]
10use std::{thread, time};
11
12use super::TMorse;
13
14mod iterator;
15use iterator::*;
16
17mod converters;
18pub use converters::*;
19
20#[derive(Debug, PartialEq, Clone)]
22pub struct Morse {
23 morse_str: Vec<MorseChar>,
24 display_as: DisplayChars,
25 #[cfg(feature = "audio")]
26 sound: Sound,
27 from_char_converter: fn(char) -> MorseResult<Vec<MorseUnit>>,
28 into_char_converter: fn(Vec<MorseUnit>) -> MorseResult<char>,
29}
30
31impl TMorse for Morse {
32 fn parse_text(&mut self, text: &str) -> MorseResult<()> {
34 let mut morse: Vec<MorseChar> = Vec::new();
35
36 for letter in text.chars() {
37 morse.push(MorseChar::from_char(letter, self.from_char_converter)?);
38 }
39
40 Ok(())
41 }
42
43 fn parse_bin(&mut self, bin: &str) -> MorseResult<()> {
45 let words: Vec<&str> = bin.split("0000000").collect();
46
47 for word in words {
48 let letters: Vec<&str> = word.split("000").collect();
49
50 for letter in letters {
51 self.morse_str
52 .push(MorseChar::from_bin(letter, self.into_char_converter)?);
53 }
54 }
55
56 Ok(())
57 }
58
59 fn len(&self) -> usize {
60 self.morse_str.len()
61 }
62
63 fn remove(&mut self, idx: usize) -> MorseChar {
64 self.morse_str.remove(idx)
65 }
66}
67
68impl Index<usize> for Morse {
69 type Output = MorseChar;
70
71 fn index(&self, idx: usize) -> &Self::Output {
72 &self.morse_str[idx]
73 }
74}
75
76impl Morse {
77 pub fn from_text(text: &str) -> MorseResult<Morse> {
88 let mut morse_str: Vec<MorseChar> = Vec::new();
89
90 for letter in text.chars() {
91 morse_str.push(MorseChar::from_char(letter, from_int_char)?);
92 }
93
94 Ok(Morse {
95 morse_str,
96 ..Morse::default()
97 })
98 }
99
100 pub fn from_bin(bin: &str) -> MorseResult<Morse> {
111 let words: Vec<&str> = bin.split("0000000").collect();
112 let mut morse_str: Vec<MorseChar> = Vec::new();
113
114 for word in words {
115 let letters: Vec<&str> = word.split("000").collect();
116
117 for letter in letters {
118 morse_str.push(MorseChar::from_bin(letter, into_int_char)?);
119 }
120 }
121
122 Ok(Morse {
123 morse_str,
124 ..Morse::default()
125 })
126 }
127
128
129
130 pub fn dot_as(&mut self, alias: &str) {
142 self.display_as.dot = alias.to_string();
143 }
144 pub fn line_as(&mut self, alias: &str) {
156 self.display_as.line = alias.to_string();
157 }
158 pub fn whitespace_as(&mut self, alias: &str) {
170 self.display_as.whitespace = alias.to_string();
171 }
172
173 #[cfg(feature = "audio")]
180 pub fn to_beep(&self) {
181 let morse_str = RefCell::new(self.morse_str.clone());
182 for (idx, m_char) in morse_str.borrow_mut().iter_mut().enumerate() {
183 m_char.frequency(self.sound.frequency);
184 m_char.play_speed(self.sound.speed);
185
186 m_char.to_beep();
187
188 if idx < self.morse_str.len() - 1 {
190 thread::sleep(time::Duration::from_secs(3));
191 }
192 }
193 }
194
195 #[cfg(feature = "audio")]
210 pub fn frequency(&mut self, frequency: f32) {
211 self.sound.frequency = frequency;
212 }
213
214 #[cfg(feature = "audio")]
233 pub fn play_speed(&mut self, speed: f32) {
234 self.sound.speed = speed;
235 }
236 pub fn to_bin_str(&self) -> String {
247 let mut string = String::new();
248
249 for (idx, m_char) in self.morse_str.iter().enumerate() {
250 string.push_str(&m_char.to_bin_str());
251
252 if idx < self.morse_str.len() - 1 {
254 string.push_str("000");
255 }
256 }
257
258 string
259 }
260 pub fn to_text(&self) -> String {
272 let mut text = String::new();
273
274 for m_char in &self.morse_str {
275 text.push(m_char.get_letter());
276 }
277
278 text
279 }
280
281 pub fn iter(&self) -> MorseIterator {
291 MorseIterator::init(self)
292 }
293}
294
295impl IntoIterator for Morse {
296 type Item = MorseChar;
297 type IntoIter = MorseIntoIterator;
298
299 fn into_iter(self) -> MorseIntoIterator {
308 MorseIntoIterator { morse: self }
309 }
310}
311
312impl Default for Morse {
313 fn default() -> Self {
314 Self {
315 morse_str: Vec::new(),
316 display_as: DisplayChars::default(),
317 #[cfg(feature = "audio")]
318 sound: Sound::default(),
319 from_char_converter: from_int_char,
320 into_char_converter: into_int_char,
321 }
322 }
323}
324
325impl ToString for Morse {
326 fn to_string(&self) -> String {
328 let mut string = String::new();
329 let morse = RefCell::new(self.morse_str.clone());
330
331 for (idx, m_char) in morse.borrow_mut().iter_mut().enumerate() {
332 m_char.dot_as(&self.display_as.dot);
333 m_char.line_as(&self.display_as.line);
334 m_char.whitespace_as(&self.display_as.whitespace);
335 string.push_str(&m_char.to_string());
336
337 if idx < self.morse_str.len() - 1 {
339 string.push_str(" ");
340 }
341 }
342
343 string
344 }
345}
346
347#[cfg(test)]
348mod morse_tests {
349 use super::*;
350
351 #[test]
352 fn create_from_text_str() {
353 assert_eq!(
354 Morse::from_text("Hello").unwrap().to_bin_str(),
355 "1010101000100010111010100010111010100011101110111"
356 );
357 }
358
359 #[test]
360 fn create_from_binary_str() {
361 const HELLO_BIN: &str = "1010101000100010111010100010111010100011101110111";
362 assert_eq!(Morse::from_bin(HELLO_BIN).unwrap().to_bin_str(), HELLO_BIN);
363 }
364
365 #[test]
366 fn to_string() {
367 assert_eq!(
368 Morse::from_text("hi u").unwrap().to_string(),
369 ". . . . . . . . ⚊"
370 );
371 }
372
373 #[test]
374 fn to_bin_str() {
375 assert_eq!(
376 Morse::from_text("hi u").unwrap().to_bin_str(),
377 "101010100010100000001010111"
378 );
379 }
380 #[test]
381 fn set_aliases_for_whitespace_lines_and_dots() {
382 let mut morse = Morse::from_text("hi u").unwrap();
383
384 morse.dot_as("🔥");
385 morse.line_as("➖");
386 morse.whitespace_as("🚧");
387
388 assert_eq!(morse.to_string(), "🔥 🔥 🔥 🔥 🔥 🔥 🚧 🔥 🔥 ➖");
389 }
390}