ssip_client_async/
client.rs

1// ssip-client -- Speech Dispatcher client in Rust
2// Copyright (c) 2021-2022 Laurent Pelecq
3//
4// Licensed under the Apache License, Version 2.0
5// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
6// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7// option. All files in the project carrying such notice may not be copied,
8// modified, or distributed except according to those terms.
9
10use std::io::{self, Read, Write};
11
12use crate::constants::*;
13use crate::protocol::{
14    flush_lines, parse_event_id, parse_single_integer, parse_single_value, parse_typed_lines,
15    write_lines,
16};
17use crate::types::*;
18
19// Trick to have common implementation for std and mio streams..
20#[cfg(unix)]
21pub use std::os::unix::io::AsRawFd as Source;
22
23#[cfg(feature = "async-mio")]
24pub use mio::event::Source as MioSource;
25
26/// Convert boolean to ON or OFF
27fn on_off(value: bool) -> &'static str {
28    if value {
29        "on"
30    } else {
31        "off"
32    }
33}
34
35macro_rules! send_one_line {
36    ($self:expr, $fmt:expr, $( $arg:expr ),+) => {
37        flush_lines(&mut $self.output, &[format!($fmt, $( $arg ),+).as_str()])
38    };
39    ($self:expr, $fmt:expr) => {
40        flush_lines(&mut $self.output, &[$fmt])
41    }
42}
43
44macro_rules! send_toggle {
45    ($output:expr, $fmt:expr, $val:expr) => {
46        send_one_line!($output, $fmt, on_off($val))
47    };
48    ($output:expr, $fmt:expr, $arg:expr, $val:expr) => {
49        send_one_line!($output, $fmt, $arg, on_off($val))
50    };
51}
52
53macro_rules! send_range {
54    ($output:expr, $fmt:expr, $scope:expr, $val:expr) => {
55        send_one_line!(
56            $output,
57            $fmt,
58            $scope,
59            std::cmp::max(-100, std::cmp::min(100, $val))
60        )
61    };
62}
63
64/// SSIP client on generic stream
65///
66/// There are two ways to send requests and receive responses:
67/// * Either with the generic [`Client::send`] and [`Client::receive`]
68/// * Or with the specific methods such as [`Client::set_rate`], ..., [`Client::get_rate`], ...
69pub struct Client<S: Read + Write + Source> {
70    input: io::BufReader<S>,
71    output: io::BufWriter<S>,
72}
73
74/// SSIP client on generic stream
75///
76/// There are two ways to send requests and receive responses:
77/// * Either with the generic [`Client::send`] and [`Client::receive`]
78/// * Or with the specific methods such as [`Client::set_rate`], ..., [`Client::get_rate`], ...
79#[cfg(feature = "async-mio")]
80pub struct MioClient<S: Read + Write + MioSource> {
81    input: io::BufReader<S>,
82    output: io::BufWriter<S>,
83}
84
85impl<S: Read + Write + Source> Client<S> {
86    /// Create a SSIP client on the reader and writer.
87    pub(crate) fn new(input: io::BufReader<S>, output: io::BufWriter<S>) -> Self {
88        // https://stackoverflow.com/questions/58467659/how-to-store-tcpstream-with-bufreader-and-bufwriter-in-a-data-structure
89        Self { input, output }
90    }
91
92    /// Send lines of text (terminated by a single dot).
93    pub fn send_lines(&mut self, lines: &[String]) -> ClientResult<&mut Self> {
94        const END_OF_DATA: [&str; 1] = ["."];
95        write_lines(
96            &mut self.output,
97            lines
98                .iter()
99                .map(|s| s.as_str())
100                .collect::<Vec<&str>>()
101                .as_slice(),
102        )?;
103        flush_lines(&mut self.output, &END_OF_DATA)?;
104        Ok(self)
105    }
106
107    /// Send one line of text (terminated by a single dot).
108    pub fn send_line(&mut self, line: &str) -> ClientResult<&mut Self> {
109        const END_OF_DATA: &str = ".";
110        flush_lines(&mut self.output, &[line, END_OF_DATA])?;
111        Ok(self)
112    }
113
114    /// Send a request
115    pub fn send(&mut self, request: Request) -> ClientResult<&mut Self> {
116        match request {
117            Request::SetName(client_name) => send_one_line!(
118                self,
119                "SET self CLIENT_NAME {}:{}:{}",
120                client_name.user,
121                client_name.application,
122                client_name.component
123            ),
124            Request::Speak => send_one_line!(self, "SPEAK"),
125            Request::SendLine(line) => self.send_line(&line).map(|_| ()),
126            Request::SendLines(lines) => self.send_lines(&lines).map(|_| ()),
127            Request::SpeakChar(ch) => send_one_line!(self, "CHAR {}", ch),
128            Request::SpeakKey(key) => send_one_line!(self, "KEY {}", key),
129            Request::Stop(scope) => send_one_line!(self, "STOP {}", scope),
130            Request::Cancel(scope) => send_one_line!(self, "CANCEL {}", scope),
131            Request::Pause(scope) => send_one_line!(self, "PAUSE {}", scope),
132            Request::Resume(scope) => send_one_line!(self, "RESUME {}", scope),
133            Request::SetPriority(prio) => send_one_line!(self, "SET self PRIORITY {}", prio),
134            Request::SetDebug(value) => send_toggle!(self, "SET all DEBUG {}", value),
135            Request::SetOutputModule(scope, value) => {
136                send_one_line!(self, "SET {} OUTPUT_MODULE {}", scope, value)
137            }
138            Request::GetOutputModule => send_one_line!(self, "GET OUTPUT_MODULE"),
139            Request::ListOutputModules => send_one_line!(self, "LIST OUTPUT_MODULES"),
140            Request::SetLanguage(scope, lang) => {
141                send_one_line!(self, "SET {} LANGUAGE {}", scope, lang)
142            }
143            Request::GetLanguage => send_one_line!(self, "GET LANGUAGE"),
144            Request::SetSsmlMode(value) => send_toggle!(self, "SET self SSML_MODE {}", value),
145            Request::SetPunctuationMode(scope, mode) => {
146                send_one_line!(self, "SET {} PUNCTUATION {}", scope, mode)
147            }
148            Request::SetSpelling(scope, value) => {
149                send_toggle!(self, "SET {} SPELLING {}", scope, value)
150            }
151            Request::SetCapitalLettersRecognitionMode(scope, mode) => {
152                send_one_line!(self, "SET {} CAP_LET_RECOGN {}", scope, mode)
153            }
154            Request::SetVoiceType(scope, value) => {
155                send_one_line!(self, "SET {} VOICE_TYPE {}", scope, value)
156            }
157            Request::GetVoiceType => send_one_line!(self, "GET VOICE_TYPE"),
158            Request::ListVoiceTypes => send_one_line!(self, "LIST VOICES"),
159            Request::SetSynthesisVoice(scope, value) => {
160                send_one_line!(self, "SET {} SYNTHESIS_VOICE {}", scope, value)
161            }
162            Request::ListSynthesisVoices => send_one_line!(self, "LIST SYNTHESIS_VOICES"),
163            Request::SetRate(scope, value) => send_range!(self, "SET {} RATE {}", scope, value),
164            Request::GetRate => send_one_line!(self, "GET RATE"),
165            Request::SetPitch(scope, value) => send_range!(self, "SET {} PITCH {}", scope, value),
166            Request::GetPitch => send_one_line!(self, "GET PITCH"),
167            Request::SetVolume(scope, value) => {
168                send_range!(self, "SET {} VOLUME {}", scope, value)
169            }
170            Request::GetVolume => send_one_line!(self, "GET VOLUME"),
171            Request::SetPauseContext(scope, value) => {
172                send_one_line!(self, "SET {} PAUSE_CONTEXT {}", scope, value)
173            }
174            Request::SetHistory(scope, value) => {
175                send_toggle!(self, "SET {} HISTORY {}", scope, value)
176            }
177            Request::SetNotification(ntype, value) => {
178                send_toggle!(self, "SET self NOTIFICATION {} {}", ntype, value)
179            }
180            Request::Begin => send_one_line!(self, "BLOCK BEGIN"),
181            Request::End => send_one_line!(self, "BLOCK END"),
182            Request::HistoryGetClients => send_one_line!(self, "HISTORY GET CLIENT_LIST"),
183            Request::HistoryGetClientId => send_one_line!(self, "HISTORY GET CLIENT_ID"),
184            Request::HistoryGetClientMsgs(scope, start, number) => send_one_line!(
185                self,
186                "HISTORY GET CLIENT_MESSAGES {} {}_{}",
187                scope,
188                start,
189                number
190            ),
191            Request::HistoryGetLastMsgId => send_one_line!(self, "HISTORY GET LAST"),
192            Request::HistoryGetMsg(id) => send_one_line!(self, "HISTORY GET MESSAGE {}", id),
193            Request::HistoryCursorGet => send_one_line!(self, "HISTORY CURSOR GET"),
194            Request::HistoryCursorSet(scope, pos) => {
195                send_one_line!(self, "HISTORY CURSOR SET {} {}", scope, pos)
196            }
197            Request::HistoryCursorMove(direction) => {
198                send_one_line!(self, "HISTORY CURSOR {}", direction)
199            }
200            Request::HistorySpeak(id) => send_one_line!(self, "HISTORY SAY {}", id),
201            Request::HistorySort(direction, key) => {
202                send_one_line!(self, "HISTORY SORT {} {}", direction, key)
203            }
204            Request::HistorySetShortMsgLength(length) => {
205                send_one_line!(self, "HISTORY SET SHORT_MESSAGE_LENGTH {}", length)
206            }
207            Request::HistorySetMsgTypeOrdering(ordering) => {
208                send_one_line!(
209                    self,
210                    "HISTORY SET MESSAGE_TYPE_ORDERING \"{}\"",
211                    ordering
212                        .iter()
213                        .map(|x| x.to_string())
214                        .collect::<Vec<String>>()
215                        .join(" ")
216                )
217            }
218            Request::HistorySearch(scope, condition) => {
219                send_one_line!(self, "HISTORY SEARCH {} \"{}\"", scope, condition)
220            }
221            Request::Quit => send_one_line!(self, "QUIT"),
222        }?;
223        Ok(self)
224    }
225
226    /// Set the client name. It must be the first call on startup.
227    pub fn set_client_name(&mut self, client_name: ClientName) -> ClientResult<&mut Self> {
228        self.send(Request::SetName(client_name))
229    }
230
231    /// Initiate communitation to send text to speak
232    pub fn speak(&mut self) -> ClientResult<&mut Self> {
233        self.send(Request::Speak)
234    }
235
236    /// Speak a char
237    pub fn speak_char(&mut self, ch: char) -> ClientResult<&mut Self> {
238        self.send(Request::SpeakChar(ch))
239    }
240
241    /// Speak a symbolic key name
242    pub fn speak_key(&mut self, key_name: KeyName) -> ClientResult<&mut Self> {
243        self.send(Request::SpeakKey(key_name))
244    }
245
246    /// Stop current message
247    pub fn stop(&mut self, scope: MessageScope) -> ClientResult<&mut Self> {
248        self.send(Request::Stop(scope))
249    }
250
251    /// Cancel current message
252    pub fn cancel(&mut self, scope: MessageScope) -> ClientResult<&mut Self> {
253        self.send(Request::Cancel(scope))
254    }
255
256    /// Pause current message
257    pub fn pause(&mut self, scope: MessageScope) -> ClientResult<&mut Self> {
258        self.send(Request::Pause(scope))
259    }
260
261    /// Resume current message
262    pub fn resume(&mut self, scope: MessageScope) -> ClientResult<&mut Self> {
263        self.send(Request::Resume(scope))
264    }
265
266    /// Set message priority
267    pub fn set_priority(&mut self, prio: Priority) -> ClientResult<&mut Self> {
268        self.send(Request::SetPriority(prio))
269    }
270
271    /// Set debug mode. Return the log location
272    pub fn set_debug(&mut self, value: bool) -> ClientResult<&mut Self> {
273        self.send(Request::SetDebug(value))
274    }
275
276    /// Set output module
277    pub fn set_output_module(
278        &mut self,
279        scope: ClientScope,
280        value: &str,
281    ) -> ClientResult<&mut Self> {
282        self.send(Request::SetOutputModule(scope, value.to_string()))
283    }
284
285    /// Get the current output module
286    pub fn get_output_module(&mut self) -> ClientResult<&mut Self> {
287        self.send(Request::GetOutputModule)
288    }
289
290    /// List the available output modules
291    pub fn list_output_modules(&mut self) -> ClientResult<&mut Self> {
292        self.send(Request::ListOutputModules)
293    }
294
295    /// Set language code
296    pub fn set_language(&mut self, scope: ClientScope, value: &str) -> ClientResult<&mut Self> {
297        self.send(Request::SetLanguage(scope, value.to_string()))
298    }
299
300    /// Get the current language
301    pub fn get_language(&mut self) -> ClientResult<&mut Self> {
302        self.send(Request::GetLanguage)
303    }
304
305    /// Set SSML mode (Speech Synthesis Markup Language)
306    pub fn set_ssml_mode(&mut self, mode: bool) -> ClientResult<&mut Self> {
307        self.send(Request::SetSsmlMode(mode))
308    }
309
310    /// Set punctuation mode
311    pub fn set_punctuation_mode(
312        &mut self,
313        scope: ClientScope,
314        mode: PunctuationMode,
315    ) -> ClientResult<&mut Self> {
316        self.send(Request::SetPunctuationMode(scope, mode))
317    }
318
319    /// Set spelling on or off
320    pub fn set_spelling(&mut self, scope: ClientScope, value: bool) -> ClientResult<&mut Self> {
321        self.send(Request::SetSpelling(scope, value))
322    }
323
324    /// Set capital letters recognition mode
325    pub fn set_capital_letter_recogn(
326        &mut self,
327        scope: ClientScope,
328        mode: CapitalLettersRecognitionMode,
329    ) -> ClientResult<&mut Self> {
330        self.send(Request::SetCapitalLettersRecognitionMode(scope, mode))
331    }
332
333    /// Set the voice type (MALE1, FEMALE1, …)
334    pub fn set_voice_type(&mut self, scope: ClientScope, value: &str) -> ClientResult<&mut Self> {
335        self.send(Request::SetVoiceType(scope, value.to_string()))
336    }
337
338    /// Get the current pre-defined voice
339    pub fn get_voice_type(&mut self) -> ClientResult<&mut Self> {
340        self.send(Request::GetVoiceType)
341    }
342
343    /// List the available symbolic voice names
344    pub fn list_voice_types(&mut self) -> ClientResult<&mut Self> {
345        self.send(Request::ListVoiceTypes)
346    }
347
348    /// Set the voice
349    pub fn set_synthesis_voice(
350        &mut self,
351        scope: ClientScope,
352        value: &str,
353    ) -> ClientResult<&mut Self> {
354        self.send(Request::SetSynthesisVoice(scope, value.to_string()))
355    }
356
357    /// Lists the available voices for the current synthesizer
358    pub fn list_synthesis_voices(&mut self) -> ClientResult<&mut Self> {
359        self.send(Request::ListSynthesisVoices)
360    }
361
362    /// Set the rate of speech. n is an integer value within the range from -100 to 100, lower values meaning slower speech.
363    pub fn set_rate(&mut self, scope: ClientScope, value: i8) -> ClientResult<&mut Self> {
364        self.send(Request::SetRate(scope, value))
365    }
366
367    /// Get the current rate of speech.
368    pub fn get_rate(&mut self) -> ClientResult<&mut Self> {
369        self.send(Request::GetRate)
370    }
371
372    /// Set the pitch of speech. n is an integer value within the range from -100 to 100.
373    pub fn set_pitch(&mut self, scope: ClientScope, value: i8) -> ClientResult<&mut Self> {
374        self.send(Request::SetPitch(scope, value))
375    }
376
377    /// Get the current pitch value.
378    pub fn get_pitch(&mut self) -> ClientResult<&mut Self> {
379        self.send(Request::GetPitch)
380    }
381
382    /// Set the volume of speech. n is an integer value within the range from -100 to 100.
383    pub fn set_volume(&mut self, scope: ClientScope, value: i8) -> ClientResult<&mut Self> {
384        self.send(Request::SetVolume(scope, value))
385    }
386
387    /// Get the current volume.
388    pub fn get_volume(&mut self) -> ClientResult<&mut Self> {
389        self.send(Request::GetVolume)
390    }
391
392    /// Set the number of (more or less) sentences that should be repeated after a previously paused text is resumed.
393    pub fn set_pause_context(&mut self, scope: ClientScope, value: u32) -> ClientResult<&mut Self> {
394        self.send(Request::SetPauseContext(scope, value))
395    }
396
397    /// Enable notification events
398    pub fn set_notification(
399        &mut self,
400        ntype: NotificationType,
401        value: bool,
402    ) -> ClientResult<&mut Self> {
403        self.send(Request::SetNotification(ntype, value))
404    }
405
406    /// Open a block
407    pub fn block_begin(&mut self) -> ClientResult<&mut Self> {
408        self.send(Request::Begin)
409    }
410
411    /// End a block
412    pub fn block_end(&mut self) -> ClientResult<&mut Self> {
413        self.send(Request::End)
414    }
415
416    /// Enable or disable history of received messages.
417    pub fn set_history(&mut self, scope: ClientScope, value: bool) -> ClientResult<&mut Self> {
418        self.send(Request::SetHistory(scope, value))
419    }
420
421    /// Get clients in history.
422    pub fn history_get_clients(&mut self) -> ClientResult<&mut Self> {
423        self.send(Request::HistoryGetClients)
424    }
425
426    /// Get client id in the history.
427    pub fn history_get_client_id(&mut self) -> ClientResult<&mut Self> {
428        self.send(Request::HistoryGetClientId)
429    }
430
431    /// Get last message said.
432    pub fn history_get_last(&mut self) -> ClientResult<&mut Self> {
433        self.send(Request::HistoryGetLastMsgId)
434    }
435
436    /// Get a range of client messages.
437    pub fn history_get_client_messages(
438        &mut self,
439        scope: ClientScope,
440        start: u32,
441        number: u32,
442    ) -> ClientResult<&mut Self> {
443        self.send(Request::HistoryGetClientMsgs(scope, start, number))
444    }
445
446    /// Get the id of the last message sent by the client.
447    pub fn history_get_last_message_id(&mut self) -> ClientResult<&mut Self> {
448        self.send(Request::HistoryGetLastMsgId)
449    }
450
451    /// Return the text of an history message.
452    pub fn history_get_message(&mut self, msg_id: MessageId) -> ClientResult<&mut Self> {
453        self.send(Request::HistoryGetMsg(msg_id))
454    }
455
456    /// Get the id of the message the history cursor is pointing to.
457    pub fn history_get_cursor(&mut self) -> ClientResult<&mut Self> {
458        self.send(Request::HistoryCursorGet)
459    }
460
461    /// Set the history cursor position.
462    pub fn history_set_cursor(
463        &mut self,
464        scope: ClientScope,
465        pos: HistoryPosition,
466    ) -> ClientResult<&mut Self> {
467        self.send(Request::HistoryCursorSet(scope, pos))
468    }
469
470    /// Move the cursor position backward or forward.
471    pub fn history_move_cursor(&mut self, direction: CursorDirection) -> ClientResult<&mut Self> {
472        self.send(Request::HistoryCursorMove(direction))
473    }
474
475    /// Speak the message from history.
476    pub fn history_speak(&mut self, msg_id: MessageId) -> ClientResult<&mut Self> {
477        self.send(Request::HistorySpeak(msg_id))
478    }
479
480    /// Sort messages in history.
481    pub fn history_sort(
482        &mut self,
483        direction: SortDirection,
484        key: SortKey,
485    ) -> ClientResult<&mut Self> {
486        self.send(Request::HistorySort(direction, key))
487    }
488
489    /// Set the maximum length of short versions of history messages.
490    pub fn history_set_short_message_length(&mut self, length: u32) -> ClientResult<&mut Self> {
491        self.send(Request::HistorySetShortMsgLength(length))
492    }
493
494    /// Set the ordering of the message types, from the minimum to the maximum.
495    pub fn history_set_ordering(&mut self, ordering: Vec<Ordering>) -> ClientResult<&mut Self> {
496        self.send(Request::HistorySetMsgTypeOrdering(ordering))
497    }
498
499    /// Search in message history.
500    pub fn history_search(
501        &mut self,
502        scope: ClientScope,
503        condition: &str,
504    ) -> ClientResult<&mut Self> {
505        self.send(Request::HistorySearch(scope, condition.to_string()))
506    }
507
508    /// Close the connection
509    pub fn quit(&mut self) -> ClientResult<&mut Self> {
510        self.send(Request::Quit)
511    }
512
513    /// Receive answer from server
514    fn receive_answer(&mut self, lines: &mut Vec<String>) -> ClientStatus {
515        crate::protocol::receive_answer(&mut self.input, Some(lines))
516    }
517
518    /// Receive one response.
519    pub fn receive(&mut self) -> ClientResult<Response> {
520        const MSG_CURSOR_SET_FIRST: &str = "OK CURSOR SET FIRST";
521        let mut lines = Vec::new();
522        let status = self.receive_answer(&mut lines)?;
523        match status.code {
524            OK_LANGUAGE_SET => Ok(Response::LanguageSet),
525            OK_PRIORITY_SET => Ok(Response::PrioritySet),
526            OK_RATE_SET => Ok(Response::RateSet),
527            OK_PITCH_SET => Ok(Response::PitchSet),
528            OK_PUNCTUATION_SET => Ok(Response::PunctuationSet),
529            OK_CAP_LET_RECOGN_SET => Ok(Response::CapLetRecognSet),
530            OK_SPELLING_SET => Ok(Response::SpellingSet),
531            OK_CLIENT_NAME_SET => Ok(Response::ClientNameSet),
532            OK_VOICE_SET => Ok(Response::VoiceSet),
533            OK_STOPPED => Ok(Response::Stopped),
534            OK_PAUSED => Ok(Response::Paused),
535            OK_RESUMED => Ok(Response::Resumed),
536            OK_CANCELED => Ok(Response::Canceled),
537            OK_TABLE_SET => Ok(Response::TableSet),
538            OK_OUTPUT_MODULE_SET => Ok(Response::OutputModuleSet),
539            OK_PAUSE_CONTEXT_SET => Ok(Response::PauseContextSet),
540            OK_VOLUME_SET => Ok(Response::VolumeSet),
541            OK_SSML_MODE_SET => Ok(Response::SsmlModeSet),
542            // Warning OK_CUR_SET_FIRST == OK_NOTIFICATION_SET == 220. Matching message to make the difference
543            OK_NOTIFICATION_SET => {
544                if status.message == MSG_CURSOR_SET_FIRST {
545                    //OK_CUR_SET_FIRST => Ok(Response::HistoryCurSetFirst)
546                    Ok(Response::HistoryCurSetFirst)
547                } else {
548                    Ok(Response::NotificationSet)
549                }
550            }
551            OK_CUR_SET_LAST => Ok(Response::HistoryCurSetLast),
552            OK_CUR_SET_POS => Ok(Response::HistoryCurSetPos),
553            OK_PITCH_RANGE_SET => Ok(Response::PitchRangeSet),
554            OK_DEBUG_SET => Ok(Response::DebugSet),
555            OK_CUR_MOV_FOR => Ok(Response::HistoryCurMoveFor),
556            OK_CUR_MOV_BACK => Ok(Response::HistoryCurMoveBack),
557            OK_MESSAGE_QUEUED => Ok(Response::MessageQueued),
558            OK_SND_ICON_QUEUED => Ok(Response::SoundIconQueued),
559            OK_MSG_CANCELED => Ok(Response::MessageCanceled),
560            OK_RECEIVING_DATA => Ok(Response::ReceivingData),
561            OK_BYE => Ok(Response::Bye),
562            OK_CLIENTS_LIST_SENT => Ok(Response::HistoryClientListSent(parse_typed_lines::<
563                HistoryClientStatus,
564            >(&lines)?)),
565            OK_MSGS_LIST_SENT => Ok(Response::HistoryMsgsListSent(lines)),
566            OK_LAST_MSG => Ok(Response::HistoryLastMsg(parse_single_value(&lines)?)),
567            OK_CUR_POS_RET => Ok(Response::HistoryCurPosRet(parse_single_value(&lines)?)),
568            OK_TABLE_LIST_SENT => Ok(Response::TableListSent(lines)),
569            OK_CLIENT_ID_SENT => Ok(Response::HistoryClientIdSent(parse_single_integer(&lines)?)),
570            OK_MSG_TEXT_SENT => Ok(Response::MessageTextSent),
571            OK_HELP_SENT => Ok(Response::HelpSent(lines)),
572            OK_VOICES_LIST_SENT => Ok(Response::VoicesListSent(
573                parse_typed_lines::<SynthesisVoice>(&lines)?,
574            )),
575            OK_OUTPUT_MODULES_LIST_SENT => Ok(Response::OutputModulesListSent(lines)),
576            OK_GET => Ok(Response::Get(parse_single_value(&lines)?)),
577            OK_INSIDE_BLOCK => Ok(Response::InsideBlock),
578            OK_OUTSIDE_BLOCK => Ok(Response::OutsideBlock),
579            OK_NOT_IMPLEMENTED => Ok(Response::NotImplemented),
580            EVENT_INDEX_MARK => match lines.len() {
581                0..=2 => Err(ClientError::TooFewLines),
582                3 => Ok(Response::EventIndexMark(
583                    parse_event_id(&lines)?,
584                    lines[2].to_owned(),
585                )),
586                _ => Err(ClientError::TooManyLines),
587            },
588            EVENT_BEGIN => Ok(Response::EventBegin(parse_event_id(&lines)?)),
589            EVENT_END => Ok(Response::EventEnd(parse_event_id(&lines)?)),
590            EVENT_CANCELED => Ok(Response::EventCanceled(parse_event_id(&lines)?)),
591            EVENT_PAUSED => Ok(Response::EventPaused(parse_event_id(&lines)?)),
592            EVENT_RESUMED => Ok(Response::EventResumed(parse_event_id(&lines)?)),
593            _ => panic!("error should have been caught earlier"),
594        }
595    }
596
597    /// Check status of answer, discard lines.
598    pub fn check_status(&mut self, expected_code: ReturnCode) -> ClientResult<&mut Self> {
599        crate::protocol::receive_answer(&mut self.input, None).and_then(|status| {
600            if status.code == expected_code {
601                Ok(self)
602            } else {
603                Err(ClientError::UnexpectedStatus(status.code))
604            }
605        })
606    }
607
608    /// Receive lines
609    pub fn receive_lines(&mut self, expected_code: ReturnCode) -> ClientResult<Vec<String>> {
610        let mut lines = Vec::new();
611        let status = self.receive_answer(&mut lines)?;
612        if status.code == expected_code {
613            Ok(lines)
614        } else {
615            Err(ClientError::UnexpectedStatus(status.code))
616        }
617    }
618
619    /// Receive a single string
620    pub fn receive_string(&mut self, expected_code: ReturnCode) -> ClientResult<String> {
621        self.receive_lines(expected_code)
622            .and_then(|lines| parse_single_value(&lines))
623    }
624
625    /// Receive signed 8-bit integer
626    pub fn receive_i8(&mut self) -> ClientResult<u8> {
627        self.receive_string(OK_GET).and_then(|s| {
628            s.parse()
629                .map_err(|_| ClientError::invalid_data("invalid signed integer"))
630        })
631    }
632
633    /// Receive unsigned 8-bit integer
634    pub fn receive_u8(&mut self) -> ClientResult<u8> {
635        self.receive_string(OK_GET).and_then(|s| {
636            s.parse()
637                .map_err(|_| ClientError::invalid_data("invalid unsigned 8-bit integer"))
638        })
639    }
640
641    /// Receive cursor pos
642    pub fn receive_cursor_pos(&mut self) -> ClientResult<u16> {
643        self.receive_string(OK_CUR_POS_RET).and_then(|s| {
644            s.parse()
645                .map_err(|_| ClientError::invalid_data("invalid unsigned 16-bit integer"))
646        })
647    }
648
649    /// Receive message id
650    pub fn receive_message_id(&mut self) -> ClientResult<MessageId> {
651        let mut lines = Vec::new();
652        match self.receive_answer(&mut lines)?.code {
653            OK_MESSAGE_QUEUED | OK_LAST_MSG => Ok(parse_single_integer(&lines)?),
654            _ => Err(ClientError::invalid_data("not a message id")),
655        }
656    }
657
658    /// Receive client id
659    pub fn receive_client_id(&mut self) -> ClientResult<ClientId> {
660        self.receive_string(OK_CLIENT_ID_SENT).and_then(|s| {
661            s.parse()
662                .map_err(|_| ClientError::invalid_data("invalid client id"))
663        })
664    }
665
666    /// Receive a list of synthesis voices
667    pub fn receive_synthesis_voices(&mut self) -> ClientResult<Vec<SynthesisVoice>> {
668        self.receive_lines(OK_VOICES_LIST_SENT)
669            .and_then(|lines| parse_typed_lines::<SynthesisVoice>(&lines))
670    }
671
672    /// Receive a notification
673    pub fn receive_event(&mut self) -> ClientResult<Event> {
674        let mut lines = Vec::new();
675        crate::protocol::receive_answer(&mut self.input, Some(&mut lines)).and_then(|status| {
676            if lines.len() < 2 {
677                Err(ClientError::unexpected_eof("event truncated"))
678            } else {
679                let message = &lines[0];
680                let client = &lines[1];
681                match status.code {
682                    700 => {
683                        if lines.len() != 3 {
684                            Err(ClientError::unexpected_eof("index markevent truncated"))
685                        } else {
686                            let mark = lines[3].to_owned();
687                            Ok(Event::index_mark(mark, message, client))
688                        }
689                    }
690                    701 => Ok(Event::begin(message, client)),
691                    702 => Ok(Event::end(message, client)),
692                    703 => Ok(Event::cancel(message, client)),
693                    704 => Ok(Event::pause(message, client)),
694                    705 => Ok(Event::resume(message, client)),
695                    _ => Err(ClientError::invalid_data("wrong status code for event")),
696                }
697            }
698        })
699    }
700
701    /// Receive a list of client status from history.
702    pub fn receive_history_clients(&mut self) -> ClientResult<Vec<HistoryClientStatus>> {
703        self.receive_lines(OK_CLIENTS_LIST_SENT)
704            .and_then(|lines| parse_typed_lines::<HistoryClientStatus>(&lines))
705    }
706
707    /// Check the result of `set_client_name`.
708    pub fn check_client_name_set(&mut self) -> ClientResult<&mut Self> {
709        self.check_status(OK_CLIENT_NAME_SET)
710    }
711
712    /// Check if server accept data.
713    pub fn check_receiving_data(&mut self) -> ClientResult<&mut Self> {
714        self.check_status(OK_RECEIVING_DATA)
715    }
716}
717
718#[cfg(feature = "async-mio")]
719impl<S: Read + Write + MioSource> MioClient<S> {
720    /// Create a SSIP client on the reader and writer.
721    pub(crate) fn new(input: io::BufReader<S>, output: io::BufWriter<S>) -> Self {
722        // https://stackoverflow.com/questions/58467659/how-to-store-tcpstream-with-bufreader-and-bufwriter-in-a-data-structure
723        Self { input, output }
724    }
725
726    /// Send lines of text (terminated by a single dot).
727    pub fn send_lines(&mut self, lines: &[String]) -> ClientResult<&mut Self> {
728        const END_OF_DATA: [&str; 1] = ["."];
729        write_lines(
730            &mut self.output,
731            lines
732                .iter()
733                .map(|s| s.as_str())
734                .collect::<Vec<&str>>()
735                .as_slice(),
736        )?;
737        flush_lines(&mut self.output, &END_OF_DATA)?;
738        Ok(self)
739    }
740
741    /// Send one line of text (terminated by a single dot).
742    pub fn send_line(&mut self, line: &str) -> ClientResult<&mut Self> {
743        const END_OF_DATA: &str = ".";
744        flush_lines(&mut self.output, &[line, END_OF_DATA])?;
745        Ok(self)
746    }
747
748    /// Send a request
749    pub fn send(&mut self, request: Request) -> ClientResult<&mut Self> {
750        match request {
751            Request::SetName(client_name) => send_one_line!(
752                self,
753                "SET self CLIENT_NAME {}:{}:{}",
754                client_name.user,
755                client_name.application,
756                client_name.component
757            ),
758            Request::Speak => send_one_line!(self, "SPEAK"),
759            Request::SendLine(line) => self.send_line(&line).map(|_| ()),
760            Request::SendLines(lines) => self.send_lines(&lines).map(|_| ()),
761            Request::SpeakChar(ch) => send_one_line!(self, "CHAR {}", ch),
762            Request::SpeakKey(key) => send_one_line!(self, "KEY {}", key),
763            Request::Stop(scope) => send_one_line!(self, "STOP {}", scope),
764            Request::Cancel(scope) => send_one_line!(self, "CANCEL {}", scope),
765            Request::Pause(scope) => send_one_line!(self, "PAUSE {}", scope),
766            Request::Resume(scope) => send_one_line!(self, "RESUME {}", scope),
767            Request::SetPriority(prio) => send_one_line!(self, "SET self PRIORITY {}", prio),
768            Request::SetDebug(value) => send_toggle!(self, "SET all DEBUG {}", value),
769            Request::SetOutputModule(scope, value) => {
770                send_one_line!(self, "SET {} OUTPUT_MODULE {}", scope, value)
771            }
772            Request::GetOutputModule => send_one_line!(self, "GET OUTPUT_MODULE"),
773            Request::ListOutputModules => send_one_line!(self, "LIST OUTPUT_MODULES"),
774            Request::SetLanguage(scope, lang) => {
775                send_one_line!(self, "SET {} LANGUAGE {}", scope, lang)
776            }
777            Request::GetLanguage => send_one_line!(self, "GET LANGUAGE"),
778            Request::SetSsmlMode(value) => send_toggle!(self, "SET self SSML_MODE {}", value),
779            Request::SetPunctuationMode(scope, mode) => {
780                send_one_line!(self, "SET {} PUNCTUATION {}", scope, mode)
781            }
782            Request::SetSpelling(scope, value) => {
783                send_toggle!(self, "SET {} SPELLING {}", scope, value)
784            }
785            Request::SetCapitalLettersRecognitionMode(scope, mode) => {
786                send_one_line!(self, "SET {} CAP_LET_RECOGN {}", scope, mode)
787            }
788            Request::SetVoiceType(scope, value) => {
789                send_one_line!(self, "SET {} VOICE_TYPE {}", scope, value)
790            }
791            Request::GetVoiceType => send_one_line!(self, "GET VOICE_TYPE"),
792            Request::ListVoiceTypes => send_one_line!(self, "LIST VOICES"),
793            Request::SetSynthesisVoice(scope, value) => {
794                send_one_line!(self, "SET {} SYNTHESIS_VOICE {}", scope, value)
795            }
796            Request::ListSynthesisVoices => send_one_line!(self, "LIST SYNTHESIS_VOICES"),
797            Request::SetRate(scope, value) => send_range!(self, "SET {} RATE {}", scope, value),
798            Request::GetRate => send_one_line!(self, "GET RATE"),
799            Request::SetPitch(scope, value) => send_range!(self, "SET {} PITCH {}", scope, value),
800            Request::GetPitch => send_one_line!(self, "GET PITCH"),
801            Request::SetVolume(scope, value) => {
802                send_range!(self, "SET {} VOLUME {}", scope, value)
803            }
804            Request::GetVolume => send_one_line!(self, "GET VOLUME"),
805            Request::SetPauseContext(scope, value) => {
806                send_one_line!(self, "SET {} PAUSE_CONTEXT {}", scope, value)
807            }
808            Request::SetHistory(scope, value) => {
809                send_toggle!(self, "SET {} HISTORY {}", scope, value)
810            }
811            Request::SetNotification(ntype, value) => {
812                send_toggle!(self, "SET self NOTIFICATION {} {}", ntype, value)
813            }
814            Request::Begin => send_one_line!(self, "BLOCK BEGIN"),
815            Request::End => send_one_line!(self, "BLOCK END"),
816            Request::HistoryGetClients => send_one_line!(self, "HISTORY GET CLIENT_LIST"),
817            Request::HistoryGetClientId => send_one_line!(self, "HISTORY GET CLIENT_ID"),
818            Request::HistoryGetClientMsgs(scope, start, number) => send_one_line!(
819                self,
820                "HISTORY GET CLIENT_MESSAGES {} {}_{}",
821                scope,
822                start,
823                number
824            ),
825            Request::HistoryGetLastMsgId => send_one_line!(self, "HISTORY GET LAST"),
826            Request::HistoryGetMsg(id) => send_one_line!(self, "HISTORY GET MESSAGE {}", id),
827            Request::HistoryCursorGet => send_one_line!(self, "HISTORY CURSOR GET"),
828            Request::HistoryCursorSet(scope, pos) => {
829                send_one_line!(self, "HISTORY CURSOR SET {} {}", scope, pos)
830            }
831            Request::HistoryCursorMove(direction) => {
832                send_one_line!(self, "HISTORY CURSOR {}", direction)
833            }
834            Request::HistorySpeak(id) => send_one_line!(self, "HISTORY SAY {}", id),
835            Request::HistorySort(direction, key) => {
836                send_one_line!(self, "HISTORY SORT {} {}", direction, key)
837            }
838            Request::HistorySetShortMsgLength(length) => {
839                send_one_line!(self, "HISTORY SET SHORT_MESSAGE_LENGTH {}", length)
840            }
841            Request::HistorySetMsgTypeOrdering(ordering) => {
842                send_one_line!(
843                    self,
844                    "HISTORY SET MESSAGE_TYPE_ORDERING \"{}\"",
845                    ordering
846                        .iter()
847                        .map(|x| x.to_string())
848                        .collect::<Vec<String>>()
849                        .join(" ")
850                )
851            }
852            Request::HistorySearch(scope, condition) => {
853                send_one_line!(self, "HISTORY SEARCH {} \"{}\"", scope, condition)
854            }
855            Request::Quit => send_one_line!(self, "QUIT"),
856        }?;
857        Ok(self)
858    }
859
860    /// Set the client name. It must be the first call on startup.
861    pub fn set_client_name(&mut self, client_name: ClientName) -> ClientResult<&mut Self> {
862        self.send(Request::SetName(client_name))
863    }
864
865    /// Initiate communitation to send text to speak
866    pub fn speak(&mut self) -> ClientResult<&mut Self> {
867        self.send(Request::Speak)
868    }
869
870    /// Speak a char
871    pub fn speak_char(&mut self, ch: char) -> ClientResult<&mut Self> {
872        self.send(Request::SpeakChar(ch))
873    }
874
875    /// Speak a symbolic key name
876    pub fn speak_key(&mut self, key_name: KeyName) -> ClientResult<&mut Self> {
877        self.send(Request::SpeakKey(key_name))
878    }
879
880    /// Stop current message
881    pub fn stop(&mut self, scope: MessageScope) -> ClientResult<&mut Self> {
882        self.send(Request::Stop(scope))
883    }
884
885    /// Cancel current message
886    pub fn cancel(&mut self, scope: MessageScope) -> ClientResult<&mut Self> {
887        self.send(Request::Cancel(scope))
888    }
889
890    /// Pause current message
891    pub fn pause(&mut self, scope: MessageScope) -> ClientResult<&mut Self> {
892        self.send(Request::Pause(scope))
893    }
894
895    /// Resume current message
896    pub fn resume(&mut self, scope: MessageScope) -> ClientResult<&mut Self> {
897        self.send(Request::Resume(scope))
898    }
899
900    /// Set message priority
901    pub fn set_priority(&mut self, prio: Priority) -> ClientResult<&mut Self> {
902        self.send(Request::SetPriority(prio))
903    }
904
905    /// Set debug mode. Return the log location
906    pub fn set_debug(&mut self, value: bool) -> ClientResult<&mut Self> {
907        self.send(Request::SetDebug(value))
908    }
909
910    /// Set output module
911    pub fn set_output_module(
912        &mut self,
913        scope: ClientScope,
914        value: &str,
915    ) -> ClientResult<&mut Self> {
916        self.send(Request::SetOutputModule(scope, value.to_string()))
917    }
918
919    /// Get the current output module
920    pub fn get_output_module(&mut self) -> ClientResult<&mut Self> {
921        self.send(Request::GetOutputModule)
922    }
923
924    /// List the available output modules
925    pub fn list_output_modules(&mut self) -> ClientResult<&mut Self> {
926        self.send(Request::ListOutputModules)
927    }
928
929    /// Set language code
930    pub fn set_language(&mut self, scope: ClientScope, value: &str) -> ClientResult<&mut Self> {
931        self.send(Request::SetLanguage(scope, value.to_string()))
932    }
933
934    /// Get the current language
935    pub fn get_language(&mut self) -> ClientResult<&mut Self> {
936        self.send(Request::GetLanguage)
937    }
938
939    /// Set SSML mode (Speech Synthesis Markup Language)
940    pub fn set_ssml_mode(&mut self, mode: bool) -> ClientResult<&mut Self> {
941        self.send(Request::SetSsmlMode(mode))
942    }
943
944    /// Set punctuation mode
945    pub fn set_punctuation_mode(
946        &mut self,
947        scope: ClientScope,
948        mode: PunctuationMode,
949    ) -> ClientResult<&mut Self> {
950        self.send(Request::SetPunctuationMode(scope, mode))
951    }
952
953    /// Set spelling on or off
954    pub fn set_spelling(&mut self, scope: ClientScope, value: bool) -> ClientResult<&mut Self> {
955        self.send(Request::SetSpelling(scope, value))
956    }
957
958    /// Set capital letters recognition mode
959    pub fn set_capital_letter_recogn(
960        &mut self,
961        scope: ClientScope,
962        mode: CapitalLettersRecognitionMode,
963    ) -> ClientResult<&mut Self> {
964        self.send(Request::SetCapitalLettersRecognitionMode(scope, mode))
965    }
966
967    /// Set the voice type (MALE1, FEMALE1, …)
968    pub fn set_voice_type(&mut self, scope: ClientScope, value: &str) -> ClientResult<&mut Self> {
969        self.send(Request::SetVoiceType(scope, value.to_string()))
970    }
971
972    /// Get the current pre-defined voice
973    pub fn get_voice_type(&mut self) -> ClientResult<&mut Self> {
974        self.send(Request::GetVoiceType)
975    }
976
977    /// List the available symbolic voice names
978    pub fn list_voice_types(&mut self) -> ClientResult<&mut Self> {
979        self.send(Request::ListVoiceTypes)
980    }
981
982    /// Set the voice
983    pub fn set_synthesis_voice(
984        &mut self,
985        scope: ClientScope,
986        value: &str,
987    ) -> ClientResult<&mut Self> {
988        self.send(Request::SetSynthesisVoice(scope, value.to_string()))
989    }
990
991    /// Lists the available voices for the current synthesizer
992    pub fn list_synthesis_voices(&mut self) -> ClientResult<&mut Self> {
993        self.send(Request::ListSynthesisVoices)
994    }
995
996    /// Set the rate of speech. n is an integer value within the range from -100 to 100, lower values meaning slower speech.
997    pub fn set_rate(&mut self, scope: ClientScope, value: i8) -> ClientResult<&mut Self> {
998        self.send(Request::SetRate(scope, value))
999    }
1000
1001    /// Get the current rate of speech.
1002    pub fn get_rate(&mut self) -> ClientResult<&mut Self> {
1003        self.send(Request::GetRate)
1004    }
1005
1006    /// Set the pitch of speech. n is an integer value within the range from -100 to 100.
1007    pub fn set_pitch(&mut self, scope: ClientScope, value: i8) -> ClientResult<&mut Self> {
1008        self.send(Request::SetPitch(scope, value))
1009    }
1010
1011    /// Get the current pitch value.
1012    pub fn get_pitch(&mut self) -> ClientResult<&mut Self> {
1013        self.send(Request::GetPitch)
1014    }
1015
1016    /// Set the volume of speech. n is an integer value within the range from -100 to 100.
1017    pub fn set_volume(&mut self, scope: ClientScope, value: i8) -> ClientResult<&mut Self> {
1018        self.send(Request::SetVolume(scope, value))
1019    }
1020
1021    /// Get the current volume.
1022    pub fn get_volume(&mut self) -> ClientResult<&mut Self> {
1023        self.send(Request::GetVolume)
1024    }
1025
1026    /// Set the number of (more or less) sentences that should be repeated after a previously paused text is resumed.
1027    pub fn set_pause_context(&mut self, scope: ClientScope, value: u32) -> ClientResult<&mut Self> {
1028        self.send(Request::SetPauseContext(scope, value))
1029    }
1030
1031    /// Enable notification events
1032    pub fn set_notification(
1033        &mut self,
1034        ntype: NotificationType,
1035        value: bool,
1036    ) -> ClientResult<&mut Self> {
1037        self.send(Request::SetNotification(ntype, value))
1038    }
1039
1040    /// Open a block
1041    pub fn block_begin(&mut self) -> ClientResult<&mut Self> {
1042        self.send(Request::Begin)
1043    }
1044
1045    /// End a block
1046    pub fn block_end(&mut self) -> ClientResult<&mut Self> {
1047        self.send(Request::End)
1048    }
1049
1050    /// Enable or disable history of received messages.
1051    pub fn set_history(&mut self, scope: ClientScope, value: bool) -> ClientResult<&mut Self> {
1052        self.send(Request::SetHistory(scope, value))
1053    }
1054
1055    /// Get clients in history.
1056    pub fn history_get_clients(&mut self) -> ClientResult<&mut Self> {
1057        self.send(Request::HistoryGetClients)
1058    }
1059
1060    /// Get client id in the history.
1061    pub fn history_get_client_id(&mut self) -> ClientResult<&mut Self> {
1062        self.send(Request::HistoryGetClientId)
1063    }
1064
1065    /// Get last message said.
1066    pub fn history_get_last(&mut self) -> ClientResult<&mut Self> {
1067        self.send(Request::HistoryGetLastMsgId)
1068    }
1069
1070    /// Get a range of client messages.
1071    pub fn history_get_client_messages(
1072        &mut self,
1073        scope: ClientScope,
1074        start: u32,
1075        number: u32,
1076    ) -> ClientResult<&mut Self> {
1077        self.send(Request::HistoryGetClientMsgs(scope, start, number))
1078    }
1079
1080    /// Get the id of the last message sent by the client.
1081    pub fn history_get_last_message_id(&mut self) -> ClientResult<&mut Self> {
1082        self.send(Request::HistoryGetLastMsgId)
1083    }
1084
1085    /// Return the text of an history message.
1086    pub fn history_get_message(&mut self, msg_id: MessageId) -> ClientResult<&mut Self> {
1087        self.send(Request::HistoryGetMsg(msg_id))
1088    }
1089
1090    /// Get the id of the message the history cursor is pointing to.
1091    pub fn history_get_cursor(&mut self) -> ClientResult<&mut Self> {
1092        self.send(Request::HistoryCursorGet)
1093    }
1094
1095    /// Set the history cursor position.
1096    pub fn history_set_cursor(
1097        &mut self,
1098        scope: ClientScope,
1099        pos: HistoryPosition,
1100    ) -> ClientResult<&mut Self> {
1101        self.send(Request::HistoryCursorSet(scope, pos))
1102    }
1103
1104    /// Move the cursor position backward or forward.
1105    pub fn history_move_cursor(&mut self, direction: CursorDirection) -> ClientResult<&mut Self> {
1106        self.send(Request::HistoryCursorMove(direction))
1107    }
1108
1109    /// Speak the message from history.
1110    pub fn history_speak(&mut self, msg_id: MessageId) -> ClientResult<&mut Self> {
1111        self.send(Request::HistorySpeak(msg_id))
1112    }
1113
1114    /// Sort messages in history.
1115    pub fn history_sort(
1116        &mut self,
1117        direction: SortDirection,
1118        key: SortKey,
1119    ) -> ClientResult<&mut Self> {
1120        self.send(Request::HistorySort(direction, key))
1121    }
1122
1123    /// Set the maximum length of short versions of history messages.
1124    pub fn history_set_short_message_length(&mut self, length: u32) -> ClientResult<&mut Self> {
1125        self.send(Request::HistorySetShortMsgLength(length))
1126    }
1127
1128    /// Set the ordering of the message types, from the minimum to the maximum.
1129    pub fn history_set_ordering(&mut self, ordering: Vec<Ordering>) -> ClientResult<&mut Self> {
1130        self.send(Request::HistorySetMsgTypeOrdering(ordering))
1131    }
1132
1133    /// Search in message history.
1134    pub fn history_search(
1135        &mut self,
1136        scope: ClientScope,
1137        condition: &str,
1138    ) -> ClientResult<&mut Self> {
1139        self.send(Request::HistorySearch(scope, condition.to_string()))
1140    }
1141
1142    /// Close the connection
1143    pub fn quit(&mut self) -> ClientResult<&mut Self> {
1144        self.send(Request::Quit)
1145    }
1146
1147    /// Receive answer from server
1148    fn receive_answer(&mut self, lines: &mut Vec<String>) -> ClientStatus {
1149        crate::protocol::receive_answer(&mut self.input, Some(lines))
1150    }
1151
1152    /// Receive one response.
1153    pub fn receive(&mut self) -> ClientResult<Response> {
1154        const MSG_CURSOR_SET_FIRST: &str = "OK CURSOR SET FIRST";
1155        let mut lines = Vec::new();
1156        let status = self.receive_answer(&mut lines)?;
1157        match status.code {
1158            OK_LANGUAGE_SET => Ok(Response::LanguageSet),
1159            OK_PRIORITY_SET => Ok(Response::PrioritySet),
1160            OK_RATE_SET => Ok(Response::RateSet),
1161            OK_PITCH_SET => Ok(Response::PitchSet),
1162            OK_PUNCTUATION_SET => Ok(Response::PunctuationSet),
1163            OK_CAP_LET_RECOGN_SET => Ok(Response::CapLetRecognSet),
1164            OK_SPELLING_SET => Ok(Response::SpellingSet),
1165            OK_CLIENT_NAME_SET => Ok(Response::ClientNameSet),
1166            OK_VOICE_SET => Ok(Response::VoiceSet),
1167            OK_STOPPED => Ok(Response::Stopped),
1168            OK_PAUSED => Ok(Response::Paused),
1169            OK_RESUMED => Ok(Response::Resumed),
1170            OK_CANCELED => Ok(Response::Canceled),
1171            OK_TABLE_SET => Ok(Response::TableSet),
1172            OK_OUTPUT_MODULE_SET => Ok(Response::OutputModuleSet),
1173            OK_PAUSE_CONTEXT_SET => Ok(Response::PauseContextSet),
1174            OK_VOLUME_SET => Ok(Response::VolumeSet),
1175            OK_SSML_MODE_SET => Ok(Response::SsmlModeSet),
1176            // Warning OK_CUR_SET_FIRST == OK_NOTIFICATION_SET == 220. Matching message to make the difference
1177            OK_NOTIFICATION_SET => {
1178                if status.message == MSG_CURSOR_SET_FIRST {
1179                    //OK_CUR_SET_FIRST => Ok(Response::HistoryCurSetFirst)
1180                    Ok(Response::HistoryCurSetFirst)
1181                } else {
1182                    Ok(Response::NotificationSet)
1183                }
1184            }
1185            OK_CUR_SET_LAST => Ok(Response::HistoryCurSetLast),
1186            OK_CUR_SET_POS => Ok(Response::HistoryCurSetPos),
1187            OK_PITCH_RANGE_SET => Ok(Response::PitchRangeSet),
1188            OK_DEBUG_SET => Ok(Response::DebugSet),
1189            OK_CUR_MOV_FOR => Ok(Response::HistoryCurMoveFor),
1190            OK_CUR_MOV_BACK => Ok(Response::HistoryCurMoveBack),
1191            OK_MESSAGE_QUEUED => Ok(Response::MessageQueued),
1192            OK_SND_ICON_QUEUED => Ok(Response::SoundIconQueued),
1193            OK_MSG_CANCELED => Ok(Response::MessageCanceled),
1194            OK_RECEIVING_DATA => Ok(Response::ReceivingData),
1195            OK_BYE => Ok(Response::Bye),
1196            OK_CLIENTS_LIST_SENT => Ok(Response::HistoryClientListSent(parse_typed_lines::<
1197                HistoryClientStatus,
1198            >(&lines)?)),
1199            OK_MSGS_LIST_SENT => Ok(Response::HistoryMsgsListSent(lines)),
1200            OK_LAST_MSG => Ok(Response::HistoryLastMsg(parse_single_value(&lines)?)),
1201            OK_CUR_POS_RET => Ok(Response::HistoryCurPosRet(parse_single_value(&lines)?)),
1202            OK_TABLE_LIST_SENT => Ok(Response::TableListSent(lines)),
1203            OK_CLIENT_ID_SENT => Ok(Response::HistoryClientIdSent(parse_single_integer(&lines)?)),
1204            OK_MSG_TEXT_SENT => Ok(Response::MessageTextSent),
1205            OK_HELP_SENT => Ok(Response::HelpSent(lines)),
1206            OK_VOICES_LIST_SENT => Ok(Response::VoicesListSent(
1207                parse_typed_lines::<SynthesisVoice>(&lines)?,
1208            )),
1209            OK_OUTPUT_MODULES_LIST_SENT => Ok(Response::OutputModulesListSent(lines)),
1210            OK_GET => Ok(Response::Get(parse_single_value(&lines)?)),
1211            OK_INSIDE_BLOCK => Ok(Response::InsideBlock),
1212            OK_OUTSIDE_BLOCK => Ok(Response::OutsideBlock),
1213            OK_NOT_IMPLEMENTED => Ok(Response::NotImplemented),
1214            EVENT_INDEX_MARK => match lines.len() {
1215                0..=2 => Err(ClientError::TooFewLines),
1216                3 => Ok(Response::EventIndexMark(
1217                    parse_event_id(&lines)?,
1218                    lines[2].to_owned(),
1219                )),
1220                _ => Err(ClientError::TooManyLines),
1221            },
1222            EVENT_BEGIN => Ok(Response::EventBegin(parse_event_id(&lines)?)),
1223            EVENT_END => Ok(Response::EventEnd(parse_event_id(&lines)?)),
1224            EVENT_CANCELED => Ok(Response::EventCanceled(parse_event_id(&lines)?)),
1225            EVENT_PAUSED => Ok(Response::EventPaused(parse_event_id(&lines)?)),
1226            EVENT_RESUMED => Ok(Response::EventResumed(parse_event_id(&lines)?)),
1227            _ => panic!("error should have been caught earlier"),
1228        }
1229    }
1230
1231    /// Check status of answer, discard lines.
1232    pub fn check_status(&mut self, expected_code: ReturnCode) -> ClientResult<&mut Self> {
1233        crate::protocol::receive_answer(&mut self.input, None).and_then(|status| {
1234            if status.code == expected_code {
1235                Ok(self)
1236            } else {
1237                Err(ClientError::UnexpectedStatus(status.code))
1238            }
1239        })
1240    }
1241
1242    /// Receive lines
1243    pub fn receive_lines(&mut self, expected_code: ReturnCode) -> ClientResult<Vec<String>> {
1244        let mut lines = Vec::new();
1245        let status = self.receive_answer(&mut lines)?;
1246        if status.code == expected_code {
1247            Ok(lines)
1248        } else {
1249            Err(ClientError::UnexpectedStatus(status.code))
1250        }
1251    }
1252
1253    /// Receive a single string
1254    pub fn receive_string(&mut self, expected_code: ReturnCode) -> ClientResult<String> {
1255        self.receive_lines(expected_code)
1256            .and_then(|lines| parse_single_value(&lines))
1257    }
1258
1259    /// Receive signed 8-bit integer
1260    pub fn receive_i8(&mut self) -> ClientResult<u8> {
1261        self.receive_string(OK_GET).and_then(|s| {
1262            s.parse()
1263                .map_err(|_| ClientError::invalid_data("invalid signed integer"))
1264        })
1265    }
1266
1267    /// Receive unsigned 8-bit integer
1268    pub fn receive_u8(&mut self) -> ClientResult<u8> {
1269        self.receive_string(OK_GET).and_then(|s| {
1270            s.parse()
1271                .map_err(|_| ClientError::invalid_data("invalid unsigned 8-bit integer"))
1272        })
1273    }
1274
1275    /// Receive cursor pos
1276    pub fn receive_cursor_pos(&mut self) -> ClientResult<u16> {
1277        self.receive_string(OK_CUR_POS_RET).and_then(|s| {
1278            s.parse()
1279                .map_err(|_| ClientError::invalid_data("invalid unsigned 16-bit integer"))
1280        })
1281    }
1282
1283    /// Receive message id
1284    pub fn receive_message_id(&mut self) -> ClientResult<MessageId> {
1285        let mut lines = Vec::new();
1286        match self.receive_answer(&mut lines)?.code {
1287            OK_MESSAGE_QUEUED | OK_LAST_MSG => Ok(parse_single_integer(&lines)?),
1288            _ => Err(ClientError::invalid_data("not a message id")),
1289        }
1290    }
1291
1292    /// Receive client id
1293    pub fn receive_client_id(&mut self) -> ClientResult<ClientId> {
1294        self.receive_string(OK_CLIENT_ID_SENT).and_then(|s| {
1295            s.parse()
1296                .map_err(|_| ClientError::invalid_data("invalid client id"))
1297        })
1298    }
1299
1300    /// Receive a list of synthesis voices
1301    pub fn receive_synthesis_voices(&mut self) -> ClientResult<Vec<SynthesisVoice>> {
1302        self.receive_lines(OK_VOICES_LIST_SENT)
1303            .and_then(|lines| parse_typed_lines::<SynthesisVoice>(&lines))
1304    }
1305
1306    /// Receive a notification
1307    pub fn receive_event(&mut self) -> ClientResult<Event> {
1308        let mut lines = Vec::new();
1309        crate::protocol::receive_answer(&mut self.input, Some(&mut lines)).and_then(|status| {
1310            if lines.len() < 2 {
1311                Err(ClientError::unexpected_eof("event truncated"))
1312            } else {
1313                let message = &lines[0];
1314                let client = &lines[1];
1315                match status.code {
1316                    700 => {
1317                        if lines.len() != 3 {
1318                            Err(ClientError::unexpected_eof("index markevent truncated"))
1319                        } else {
1320                            let mark = lines[3].to_owned();
1321                            Ok(Event::index_mark(mark, message, client))
1322                        }
1323                    }
1324                    701 => Ok(Event::begin(message, client)),
1325                    702 => Ok(Event::end(message, client)),
1326                    703 => Ok(Event::cancel(message, client)),
1327                    704 => Ok(Event::pause(message, client)),
1328                    705 => Ok(Event::resume(message, client)),
1329                    _ => Err(ClientError::invalid_data("wrong status code for event")),
1330                }
1331            }
1332        })
1333    }
1334
1335    /// Receive a list of client status from history.
1336    pub fn receive_history_clients(&mut self) -> ClientResult<Vec<HistoryClientStatus>> {
1337        self.receive_lines(OK_CLIENTS_LIST_SENT)
1338            .and_then(|lines| parse_typed_lines::<HistoryClientStatus>(&lines))
1339    }
1340
1341    /// Check the result of `set_client_name`.
1342    pub fn check_client_name_set(&mut self) -> ClientResult<&mut Self> {
1343        self.check_status(OK_CLIENT_NAME_SET)
1344    }
1345
1346    /// Check if server accept data.
1347    pub fn check_receiving_data(&mut self) -> ClientResult<&mut Self> {
1348        self.check_status(OK_RECEIVING_DATA)
1349    }
1350
1351    /// Register the socket for polling.
1352    #[cfg(feature = "async-mio")]
1353    pub fn register(
1354        &mut self,
1355        poll: &mio::Poll,
1356        input_token: mio::Token,
1357        output_token: mio::Token,
1358    ) -> io::Result<()> {
1359        poll.registry()
1360            .register(self.input.get_mut(), input_token, mio::Interest::READABLE)?;
1361        poll.registry()
1362            .register(self.output.get_mut(), output_token, mio::Interest::WRITABLE)?;
1363        Ok(())
1364    }
1365}