1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use std::boxed::Box;
use std::convert;
use std::fmt;
use std::io;
use failure::Fail;
mod backends;
pub enum Backends {
#[cfg(target_os = "linux")]
SpeechDispatcher,
#[cfg(target_arch = "wasm32")]
Web,
}
#[derive(Debug, Fail)]
pub struct Error(String);
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "{}", self.0)?;
Ok(())
}
}
impl convert::From<Error> for io::Error {
fn from(e: Error) -> io::Error {
io::Error::new(io::ErrorKind::Other, e.0)
}
}
trait Backend {
fn speak(&self, text: &str, interrupt: bool) -> Result<(), Error>;
fn stop(&self) -> Result<(), Error>;
fn get_rate(&self) -> Result<u8, Error>;
fn set_rate(&mut self, rate: u8) -> Result<(), Error>;
fn get_pitch(&self) -> Result<u8, Error>;
fn set_pitch(&mut self, pitch: u8) -> Result<(), Error>;
fn get_volume(&self) -> Result<u8, Error>;
fn set_volume(&mut self, volume: u8) -> Result<(), Error>;
}
pub struct TTS(Box<Backend>);
unsafe impl std::marker::Send for TTS {}
unsafe impl std::marker::Sync for TTS {}
impl TTS {
pub fn new(backend: Backends) -> Result<TTS, Error> {
match backend {
#[cfg(target_os = "linux")]
Backends::SpeechDispatcher => Ok(TTS(Box::new(backends::SpeechDispatcher::new()))),
#[cfg(target_arch = "wasm32")]
Backends::Web => {
let tts = backends::Web::new()?;
Ok(TTS(Box::new(tts)))
}
}
}
pub fn default() -> Result<TTS, Error> {
#[cfg(target_os = "linux")]
let tts = TTS::new(Backends::SpeechDispatcher);
#[cfg(target_arch = "wasm32")]
let tts = TTS::new(Backends::Web);
tts
}
pub fn speak<S: Into<String>>(&self, text: S, interrupt: bool) -> Result<&Self, Error> {
self.0.speak(text.into().as_str(), interrupt)?;
Ok(self)
}
pub fn stop(&self) -> Result<&Self, Error> {
self.0.stop()?;
Ok(self)
}
pub fn get_rate(&self) -> Result<u8, Error> {
self.0.get_rate()
}
pub fn set_rate(&mut self, rate: u8) -> Result<&Self, Error> {
self.0.set_rate(rate)?;
Ok(self)
}
pub fn get_pitch(&self) -> Result<u8, Error> {
self.0.get_pitch()
}
pub fn set_pitch(&mut self, pitch: u8) -> Result<&Self, Error> {
self.0.set_pitch(pitch)?;
Ok(self)
}
pub fn get_volume(&self) -> Result<u8, Error> {
self.0.get_volume()
}
pub fn set_volume(&mut self, volume: u8) -> Result<&Self, Error> {
self.0.set_volume(volume)?;
Ok(self)
}
}