You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

125 lines
4.1 KiB

#[cfg(all(unix, not(feature = "async-mio")))]
use std::{
collections::VecDeque,
io::{self, Write},
};
#[cfg(all(unix, not(feature = "async-mio")))]
use ssip_client::{fifo, ClientError, ClientName, ClientResult, QueuedClient, Request, Response};
#[cfg(all(unix, not(feature = "async-mio")))]
fn main() -> ClientResult<()> {
#[derive(Clone, Eq, PartialEq)]
enum SourceKey {
Stdin,
SpeechIn,
SpeechOut,
}
let mut sources = popol::Sources::with_capacity(2);
let mut events = popol::Events::with_capacity(4);
let stdin = io::stdin();
let mut ssip_client = QueuedClient::new(fifo::Builder::new().nonblocking().build()?);
sources.register(SourceKey::Stdin, &stdin, popol::interest::READ);
sources.register(
SourceKey::SpeechIn,
ssip_client.input_source(),
popol::interest::READ,
);
sources.register(
SourceKey::SpeechOut,
ssip_client.output_source(),
popol::interest::WRITE,
);
// Loop for events
let mut speech_writable = false;
let mut send_requests = VecDeque::with_capacity(4);
ssip_client.push(Request::SetName(ClientName::new("joe", "async")));
fn prompt() -> io::Result<()> {
let mut stdout = io::stdout();
write!(stdout, "> ")?;
stdout.flush()
}
println!("Enter an empty line to quit.");
prompt()?;
loop {
sources.wait(&mut events)?;
for (key, _event) in events.iter() {
match key {
SourceKey::Stdin => {
let mut text = String::new();
stdin.read_line(&mut text)?;
text = text.trim_end().to_string();
match text.len() {
0 => return Ok(()),
1 => {
if let Some(ch) = text.chars().next() {
println!("sending char: {}", ch);
ssip_client.push(Request::SpeakChar(ch))
}
}
_ => {
println!("sending line: {}", text);
send_requests.push_back(Request::SendLine(text.to_owned()));
ssip_client.push(Request::Speak);
}
}
prompt()?;
}
SourceKey::SpeechIn => match ssip_client.receive_next() {
Err(ClientError::Io(err)) => return Err(ClientError::from(err)),
Err(ClientError::Ssip(err)) => eprintln!("SSIP error: {:?}", err),
Err(_) => panic!("internal error"),
Ok(result) => match result {
Response::MessageQueued | Response::ClientNameSet => (),
Response::ReceivingData => {
ssip_client.push(send_requests.pop_front().unwrap())
}
_ => panic!("Unexpected response: {:?}", result),
},
},
SourceKey::SpeechOut => {
speech_writable = true;
}
}
}
if speech_writable {
if sources.len() >= 3 {
sources.unregister(&SourceKey::SpeechOut);
}
loop {
match ssip_client.send_next() {
Err(ClientError::NotReady) => speech_writable = false,
Err(ClientError::Io(err)) => return Err(ClientError::from(err)),
Err(_) => panic!("internal error"),
Ok(true) => (),
Ok(false) => break,
}
}
}
if !speech_writable && ssip_client.has_next() {
sources.register(
SourceKey::SpeechOut,
ssip_client.output_source(),
popol::interest::WRITE,
);
}
}
}
#[cfg(all(unix, feature = "async-mio"))]
fn main() {
println!("asynchronous client not implemented");
}
#[cfg(not(unix))]
fn main() {
println!("example only available on unix.");
}