1#[cfg(test)]
6mod tests {
7 use super::*;
8
9 #[test]
10 fn talk_request_body_is_formatting_with_text_script() {
11 let talk_req_bod = TalkRequestBody {
12 source_url: "www.dummyurl.com".to_string(),
13 driver_url: None,
14 script: Script::Text {
15 r#type: "text".to_string(),
16 subtitles: false,
17 provider: Some(TTSProvider::MicrosoftTTS {
18 r#type: "microsoft".to_string(),
19 voice_id: "en-US-JennyNeural".to_string(),
20 }),
21 input: "Hello world!".to_string(),
22 ssml: false,
23 },
24 config: None,
25 user_data: "".to_string(),
26 name: "".to_string(),
27 webhook: "".to_string(),
28 result_url: "".to_string(),
29 face: None,
30 persist: false,
31 };
32
33 let talk_req_bod2 = TalkRequestBodyBuilder::with_text_script().unwrap()
34 .source_url("www.dummyurl.com").unwrap()
35 .input("Hello world!").unwrap()
36 .build().unwrap();
37
38 let want = serde_json::to_string(&talk_req_bod).unwrap();
39 let got = serde_json::to_string(&talk_req_bod2).unwrap();
40
41 assert_eq!(want, got);
42
43
44 }
45
46 #[test]
47 fn talk_request_body_is_formatting_with_audio_script() {
48 let talk_req_bod = TalkRequestBody {
49 source_url: "www.dummyurl.com".to_string(),
50 driver_url: None,
51 script: Script::Audio {
52 r#type: "audio".to_string(),
53 subtitles: false,
54 audio_url: "www.dummyaudiourl.com".to_string(),
55 reduce_noise: false,
56 },
57 config: None,
58 user_data: "".to_string(),
59 name: "".to_string(),
60 webhook: "".to_string(),
61 result_url: "".to_string(),
62 face: None,
63 persist: false,
64 };
65
66 let talk_req_bod2 = TalkRequestBodyBuilder::with_audio_script().unwrap()
67 .source_url("www.dummyurl.com").unwrap()
68 .audio_url("www.dummyaudiourl.com").unwrap()
69 .build().unwrap();
70
71 let want = serde_json::to_string(&talk_req_bod).unwrap();
72 let got = serde_json::to_string(&talk_req_bod2).unwrap();
73
74 assert_eq!(want, got);
75 }
76}
77
78
79use super::*;
80
81
82const TALKS_PATH: &str = "/talks";
83
84#[derive(Serialize, Deserialize, Debug)]
85pub struct TalkRequestBody {
86 source_url: String,
87 #[serde(skip_serializing_if = "Option::is_none")]
88 driver_url: Option<Driver>,
89 script: Script,
90 #[serde(skip_serializing_if = "Option::is_none")]
91 config: Option<Config>,
92 #[serde(skip_serializing_if = "String::is_empty")]
93 user_data: String,
94 #[serde(skip_serializing_if = "String::is_empty")]
95 name: String,
96 #[serde(skip_serializing_if = "String::is_empty")]
97 webhook: String,
98 #[serde(skip_serializing_if = "String::is_empty")]
99 result_url: String,
100 #[serde(skip_serializing_if = "Option::is_none")]
101 face: Option<Face>,
102 persist: bool,
103}
104
105impl TalkRequestBody {
106 pub async fn create_talk(&self) -> Result<CreateTalkResponse> {
107 let c = ClientBuilder::new()?
108 .method(POST)?
109 .path(TALKS_PATH)?
110 .header(CONTENT_TYPE, APPLICATION_JSON)?
111 .build()?;
112
113 let resp = c.send_request(Full::<Bytes>::new(serde_json::to_string(&self)?.into())).await?;
114
115 let talk_resp= serde_json::from_slice::<CreateTalkResponse>(&resp.as_ref())?;
116
117 Ok(talk_resp)
118 }
119
120
121}
122pub async fn get_talk(id: &str) -> Result<GetTalkResponse> {
123 let c = ClientBuilder::new()?
124 .method(GET)?
125 .path(&format!("{}/{}", TALKS_PATH, id))?
126 .header(CONTENT_TYPE, APPLICATION_JSON)?
127 .build()?;
128
129 let resp = c.send_request(Empty::<Bytes>::new()).await?;
130
131 let json = serde_json::from_slice::<GetTalkResponse>(&resp.as_ref())?;
132
133 Ok(json)
134}
135
136pub async fn get_talks() -> Result<GetTalksResponse> {
137 let c = ClientBuilder::new()?
138 .method(GET)?
139 .path(TALKS_PATH)?
140 .header(CONTENT_TYPE, APPLICATION_JSON)?
141 .build()?;
142
143 let resp = c.send_request(Empty::<Bytes>::new()).await?;
144
145 let json = serde_json::from_slice::<GetTalksResponse>(&resp.as_ref())?;
146
147 Ok(json)
148}
149
150pub async fn delete_talk(id: &str) -> Result<()> {
151 let c = ClientBuilder::new()?
152 .method(DELETE)?
153 .path(&format!("{}/{}", TALKS_PATH, id))?
154 .header(CONTENT_TYPE, APPLICATION_JSON)?
155 .build()?;
156
157 let _resp = c.send_request(Empty::<Bytes>::new()).await?;
158
159 Ok(())
160}
161
162#[derive(Serialize, Deserialize, Debug)]
163pub struct CreateTalkResponse {
164 pub id: String,
165 pub object: String,
166 pub created_by: String,
167 pub created_at: String,
168 pub status: String,
169}
170
171#[derive(Serialize, Deserialize, Debug)]
172pub struct GetTalkResponse {
173 pub id: String,
174 pub user_id: String,
175 pub source_url: String,
176 pub created_at: String,
177 pub audio_url: String,
178 pub started_at: String,
179 pub modified_at: String,
180 pub status: String,
181 pub result_url: String,
182}
183
184#[derive(Serialize, Deserialize, Debug)]
185pub struct GetTalksResponse {
186 pub talks: Vec<GetTalkResponse>,
187}
188
189
190
191pub struct TalkRequestBodyBuilder {
192 source_url: Option<String>,
193 driver_url: Option<Driver>,
194 script: Option<Script>,
195 config: Option<Config>,
196 user_data: Option<String>,
197 name: Option<String>,
198 webhook: Option<String>,
199 result_url: Option<String>,
200 face: Option<Face>,
201 persist: Option<bool>,
202}
203
204impl TalkRequestBodyBuilder {
205 pub fn with_text_script() -> Self {
206 let script = Script::Text {
207 r#type: "text".to_string(),
208 subtitles: false,
209 provider: Some(TTSProvider::MicrosoftTTS {
210 r#type: "microsoft".to_string(),
211 voice_id: "en-US-JennyNeural".to_string(),
212 }),
213 input: "".to_string(),
214 ssml: false,
215 };
216
217 Self {
218 source_url: None,
219 driver_url: None,
220 script: Some(script),
221 config: None,
222 user_data: None,
223 name: None,
224 webhook: None,
225 result_url: None,
226 face: None,
227 persist: None,
228 }
229 }
230
231 pub fn with_audio_script() -> Self {
232 let script = Script::Audio {
233 r#type: "audio".to_string(),
234 subtitles: false,
235 audio_url: "".to_string(),
236 reduce_noise: false,
237 };
238
239 Self {
240 source_url: None,
241 driver_url: None,
242 script: Some(script),
243 config: None,
244 user_data: None,
245 name: None,
246 webhook: None,
247 result_url: None,
248 face: None,
249 persist: None,
250 }
251 }
252 pub fn source_url(mut self, source_url: &str) -> Result<Self> {
253 self.source_url = Some(source_url.to_string());
254 Ok(self)
255 }
256
257 pub fn audio_url(mut self, audio_url: &str) -> Result<Self> {
258 if let Some(Script::Audio { audio_url: a, .. }) = self.script.as_mut() {
259 *a = audio_url.to_string();
260 }
261 Ok(self)
262 }
263
264 pub fn driver_url(mut self, driver_url: Driver) -> Result<Self> {
265 self.driver_url = Some(driver_url);
266 Ok(self)
267 }
268
269 pub fn script(mut self, script: Script) -> Result<Self> {
270 self.script = Some(script);
271 Ok(self)
272 }
273
274 pub fn user_data(mut self, user_data: &str) -> Result<Self> {
275 self.user_data = Some(user_data.to_string());
276 Ok(self)
277 }
278
279 pub fn name(mut self, name: &str) -> Result<Self> {
280 self.name = Some(name.to_string());
281 Ok(self)
282 }
283
284 pub fn webhook(mut self, webhook: &str) -> Result<Self> {
285 self.webhook = Some(webhook.to_string());
286 Ok(self)
287 }
288
289 pub fn result_url(mut self, result_url: &str) -> Result<Self> {
290 self.result_url = Some(result_url.to_string());
291 Ok(self)
292 }
293
294 pub fn persist(mut self, persist: bool) -> Result<Self> {
295 self.persist = Some(persist);
296 Ok(self)
297 }
298
299 pub fn input (mut self, input: &str) -> Result<Self> {
300 if let Some(Script::Text { input: i, .. }) = self.script.as_mut() {
301 *i = input.to_string();
302 }
303 Ok(self)
304 }
305
306 pub fn ssml(mut self, ssml: bool) -> Result<Self> {
307 if let Some(Script::Text { ssml: s, .. }) = self.script.as_mut() {
308 *s = ssml;
309 }
310 Ok(self)
311 }
312
313 pub fn subtitles(mut self, subtitles: bool) -> Result<Self> {
314 if let Some(Script::Text { subtitles: s, .. }) = self.script.as_mut() {
315 *s = subtitles;
316 }
317 Ok(self)
318 }
319
320 pub fn provider(mut self, provider: TTSProvider) -> Result<Self> {
321 if let Some(Script::Text { provider: p, .. }) = self.script.as_mut() {
322 *p = Some(provider);
323 }
324 Ok(self)
325 }
326
327 pub fn face(mut self, face: Face) -> Result<Self> {
328 self.face = Some(face);
329 Ok(self)
330 }
331
332 pub fn config(mut self, config: Config) -> Result<Self> {
333 self.config = Some(config);
334 Ok(self)
335 }
336
337 pub fn reduce_noise(mut self, reduce_noise: bool) -> Result<Self> {
338 if let Some(Script::Audio { reduce_noise: r, .. }) = self.script.as_mut() {
339 *r = reduce_noise;
340 }
341 Ok(self)
342 }
343
344
345
346 pub fn build(self) -> Result<TalkRequestBody> {
347 let source_url = self.source_url.ok_or(RequestBodyBuildError::SourceUrlNotSet)?;
348
349 let script = self.script.ok_or(Box::new(RequestBodyBuildError::ScriptNotSet))?;
350
351 Ok(
352 TalkRequestBody {
353 source_url,
354 driver_url: self.driver_url,
355 script,
356 config: self.config,
357 user_data: self.user_data.unwrap_or_default(),
358 name: self.name.unwrap_or_default(),
359 webhook: self.webhook.unwrap_or_default(),
360 result_url: self.result_url.unwrap_or_default(),
361 face: self.face,
362 persist: self.persist.unwrap_or(false),
363 }
364 )
365
366 }
367
368
369}
370