Fix compilation on non-unix platforms

main
Laurent Pelecq 2 years ago
parent c67bab22d9
commit c9c80a1b6c

@ -1,6 +1,6 @@
[package] [package]
name = "ssip-client" name = "ssip-client"
version = "0.8.0" version = "0.8.1"
authors = ["Laurent Pelecq <lpelecq+rust@circoise.eu>"] authors = ["Laurent Pelecq <lpelecq+rust@circoise.eu>"]
edition = "2018" edition = "2018"
description = "Client API for Speech Dispatcher" description = "Client API for Speech Dispatcher"
@ -22,6 +22,7 @@ async-mio = ["mio/net", "mio/os-poll"]
[dev-dependencies] [dev-dependencies]
mio = { version = "0.8", features = ["os-poll", "os-ext"] } mio = { version = "0.8", features = ["os-poll", "os-ext"] }
lazy_static = "1"
popol = "0.5" popol = "0.5"
tempfile = "3" tempfile = "3"

@ -1,16 +1,16 @@
#[cfg(feature = "async-mio")] #[cfg(all(unix, feature = "async-mio"))]
use mio::{unix::SourceFd, Events, Interest, Poll, Token}; use mio::{unix::SourceFd, Events, Interest, Poll, Token};
#[cfg(feature = "async-mio")] #[cfg(all(unix, feature = "async-mio"))]
use std::{ use std::{
collections::VecDeque, collections::VecDeque,
io::{self, Write}, io::{self, Write},
os::unix::io::AsRawFd, os::unix::io::AsRawFd,
}; };
#[cfg(feature = "async-mio")] #[cfg(all(unix, feature = "async-mio"))]
use ssip_client::{fifo, QueuedClient, ClientError, ClientName, ClientResult, Request, Response}; use ssip_client::{fifo, ClientError, ClientName, ClientResult, QueuedClient, Request, Response};
#[cfg(feature = "async-mio")] #[cfg(all(unix, feature = "async-mio"))]
fn main() -> ClientResult<()> { fn main() -> ClientResult<()> {
let stdin = io::stdin(); let stdin = io::stdin();
@ -97,7 +97,12 @@ fn main() -> ClientResult<()> {
} }
} }
#[cfg(not(feature = "async-mio"))] #[cfg(all(unix, not(feature = "async-mio")))]
fn main() { fn main() {
println!("see hello for an example of synchronous client."); println!("see hello for an example of synchronous client.");
} }
#[cfg(not(unix))]
fn main() {
println!("example only available on unix.");
}

@ -1,13 +1,13 @@
#[cfg(not(feature = "async-mio"))] #[cfg(all(unix, not(feature = "async-mio")))]
use std::{ use std::{
collections::VecDeque, collections::VecDeque,
io::{self, Write}, io::{self, Write},
}; };
#[cfg(not(feature = "async-mio"))] #[cfg(all(unix, not(feature = "async-mio")))]
use ssip_client::{fifo, ClientError, ClientName, ClientResult, QueuedClient, Request, Response}; use ssip_client::{fifo, ClientError, ClientName, ClientResult, QueuedClient, Request, Response};
#[cfg(not(feature = "async-mio"))] #[cfg(all(unix, not(feature = "async-mio")))]
fn main() -> ClientResult<()> { fn main() -> ClientResult<()> {
#[derive(Clone, Eq, PartialEq)] #[derive(Clone, Eq, PartialEq)]
enum SourceKey { enum SourceKey {
@ -113,7 +113,12 @@ fn main() -> ClientResult<()> {
} }
} }
#[cfg(feature = "async-mio")] #[cfg(all(unix, feature = "async-mio"))]
fn main() { fn main() {
println!("see async_mio_loop for an example of asynchronous client."); println!("asynchronous client not implemented");
}
#[cfg(not(unix))]
fn main() {
println!("example only available on unix.");
} }

@ -1,7 +1,7 @@
#[cfg(not(feature = "async-mio"))] #[cfg(all(unix, not(feature = "async-mio")))]
use ssip_client::{fifo, ClientName, ClientResult}; use ssip_client::{fifo, ClientName, ClientResult};
#[cfg(not(feature = "async-mio"))] #[cfg(all(unix, not(feature = "async-mio")))]
fn main() -> ClientResult<()> { fn main() -> ClientResult<()> {
let mut client = fifo::Builder::new().build()?; let mut client = fifo::Builder::new().build()?;
client client
@ -19,7 +19,12 @@ fn main() -> ClientResult<()> {
Ok(()) Ok(())
} }
#[cfg(feature = "async-mio")] #[cfg(all(unix, feature = "async-mio"))]
fn main() { fn main() {
println!("see async_mio_loop for an example of asynchronous client."); println!("see async_mio_loop for an example of asynchronous client.");
} }
#[cfg(not(unix))]
fn main() {
println!("example only available on unix.");
}

@ -1,10 +1,10 @@
#[cfg(not(feature = "async-mio"))] #[cfg(all(unix, not(feature = "async-mio")))]
use ssip_client::{ use ssip_client::{
fifo, ClientName, ClientResult, SynthesisVoice, OK_OUTPUT_MODULES_LIST_SENT, fifo, ClientName, ClientResult, SynthesisVoice, OK_OUTPUT_MODULES_LIST_SENT,
OK_VOICES_LIST_SENT, OK_VOICES_LIST_SENT,
}; };
#[cfg(not(feature = "async-mio"))] #[cfg(all(unix, not(feature = "async-mio")))]
fn main() -> ClientResult<()> { fn main() -> ClientResult<()> {
fn voice_to_string(voice: &SynthesisVoice) -> String { fn voice_to_string(voice: &SynthesisVoice) -> String {
match &voice.language { match &voice.language {
@ -54,7 +54,12 @@ fn main() -> ClientResult<()> {
Ok(()) Ok(())
} }
#[cfg(feature = "async-mio")] #[cfg(all(unix, feature = "async-mio"))]
fn main() { fn main() {
println!("asynchronous client not implemented"); println!("asynchronous client not implemented");
} }
#[cfg(not(unix))]
fn main() {
println!("example only available on unix.");
}

@ -1,9 +1,9 @@
#[cfg(not(feature = "async-mio"))] #[cfg(all(unix, not(feature = "async-mio")))]
use ssip_client::{ use ssip_client::{
fifo, ClientName, ClientResult, EventType, NotificationType, OK_NOTIFICATION_SET, fifo, ClientName, ClientResult, EventType, NotificationType, OK_NOTIFICATION_SET,
}; };
#[cfg(not(feature = "async-mio"))] #[cfg(all(unix, not(feature = "async-mio")))]
fn main() -> ClientResult<()> { fn main() -> ClientResult<()> {
let mut client = fifo::Builder::new().build()?; let mut client = fifo::Builder::new().build()?;
client client
@ -43,7 +43,12 @@ fn main() -> ClientResult<()> {
Ok(()) Ok(())
} }
#[cfg(feature = "async-mio")] #[cfg(all(unix, feature = "async-mio"))]
fn main() { fn main() {
println!("asynchronous client not implemented"); println!("asynchronous client not implemented");
} }
#[cfg(not(unix))]
fn main() {
println!("example only available on unix.");
}

@ -34,6 +34,7 @@ mod types;
pub mod client; pub mod client;
pub mod constants; pub mod constants;
#[cfg(unix)]
pub mod fifo; pub mod fifo;
pub mod net; pub mod net;
pub mod tcp; pub mod tcp;

@ -136,7 +136,7 @@ const BASIC_COMMUNICATION: [(&str, &str); 5] = [
]; ];
#[test] #[test]
#[cfg(feature = "async-mio")] #[cfg(all(unix, feature = "async-mio"))]
fn basic_async_unix_communication() -> ClientResult<()> { fn basic_async_unix_communication() -> ClientResult<()> {
let socket_dir = tempfile::tempdir()?; let socket_dir = tempfile::tempdir()?;
let socket_path = socket_dir.path().join("basic_async_communication.socket"); let socket_path = socket_dir.path().join("basic_async_communication.socket");

@ -7,11 +7,10 @@
// modified, or distributed except according to those terms. // modified, or distributed except according to those terms.
use std::io::{self, BufRead, BufReader, BufWriter, Read, Write}; use std::io::{self, BufRead, BufReader, BufWriter, Read, Write};
use std::path::Path; use std::net::{Shutdown, TcpListener, ToSocketAddrs};
use std::thread; use std::thread;
#[cfg(unix)]
use std::net::{TcpListener, ToSocketAddrs}; use std::{os::unix::net::UnixListener, path::Path};
use std::os::unix::net::UnixListener;
/// Split lines on CRLF /// Split lines on CRLF
fn split_lines(lines: &str) -> Vec<String> { fn split_lines(lines: &str) -> Vec<String> {
@ -56,10 +55,12 @@ pub trait Server {
} }
/// Server on a named socket. /// Server on a named socket.
#[cfg(unix)]
pub struct UnixServer { pub struct UnixServer {
listener: UnixListener, listener: UnixListener,
} }
#[cfg(unix)]
impl UnixServer { impl UnixServer {
/// Create a new server on a named socket. /// Create a new server on a named socket.
/// ///
@ -74,6 +75,7 @@ impl UnixServer {
} }
} }
#[cfg(unix)]
impl Server for UnixServer { impl Server for UnixServer {
fn serve(&mut self, communication: &[(&'static str, &'static str)]) -> io::Result<()> { fn serve(&mut self, communication: &[(&'static str, &'static str)]) -> io::Result<()> {
let (mut stream, _) = self.listener.accept()?; let (mut stream, _) = self.listener.accept()?;
@ -100,7 +102,8 @@ impl TcpServer {
impl Server for TcpServer { impl Server for TcpServer {
fn serve(&mut self, communication: &[(&'static str, &'static str)]) -> io::Result<()> { fn serve(&mut self, communication: &[(&'static str, &'static str)]) -> io::Result<()> {
let (mut stream, _) = self.listener.accept()?; let (mut stream, _) = self.listener.accept()?;
serve_streams(&mut stream.try_clone()?, &mut stream, communication) serve_streams(&mut stream.try_clone()?, &mut stream, communication)?;
stream.shutdown(Shutdown::Both)
} }
} }
@ -115,6 +118,7 @@ pub fn run_server(
}) })
} }
#[cfg(unix)]
pub fn run_unix<P>( pub fn run_unix<P>(
socket_path: P, socket_path: P,
communication: &'static [(&'static str, &'static str)], communication: &'static [(&'static str, &'static str)],

@ -8,11 +8,16 @@
#[cfg(not(feature = "async-mio"))] #[cfg(not(feature = "async-mio"))]
use ssip_client::{client::Source, *}; use ssip_client::{client::Source, *};
#[cfg(all(unix, not(feature = "async-mio")))]
use std::os::unix::net::UnixStream;
#[cfg(not(feature = "async-mio"))] #[cfg(not(feature = "async-mio"))]
use std::{ use std::{
io::{self, Read, Write}, io::{self, Read, Write},
net::TcpStream, net::TcpStream,
os::unix::net::UnixStream, sync::{
atomic::{AtomicU16, Ordering as AtomicOrdering},
Arc,
},
}; };
#[cfg(not(feature = "async-mio"))] #[cfg(not(feature = "async-mio"))]
@ -21,7 +26,7 @@ mod server;
/// Create a server on a Unix socket and run the client /// Create a server on a Unix socket and run the client
/// ///
/// The communication is an array of (["question", ...], "response") /// The communication is an array of (["question", ...], "response")
#[cfg(not(feature = "async-mio"))] #[cfg(all(unix, not(feature = "async-mio")))]
fn test_unix_client<F>( fn test_unix_client<F>(
communication: &'static [(&'static str, &'static str)], communication: &'static [(&'static str, &'static str)],
process: F, process: F,
@ -46,6 +51,11 @@ where
Ok(()) Ok(())
} }
#[cfg(not(feature = "async-mio"))]
lazy_static::lazy_static! {
static ref TCP_PORT: Arc<AtomicU16> = Arc::new(AtomicU16::new(10000));
}
/// Create a server on a inet socket and run the client /// Create a server on a inet socket and run the client
/// ///
/// The communication is an array of (["question", ...], "response") /// The communication is an array of (["question", ...], "response")
@ -58,9 +68,10 @@ where
F: FnMut(&mut Client<TcpStream>) -> io::Result<()>, F: FnMut(&mut Client<TcpStream>) -> io::Result<()>,
{ {
let mut process_wrapper = std::panic::AssertUnwindSafe(process); let mut process_wrapper = std::panic::AssertUnwindSafe(process);
let addr = "127.0.0.1:9999"; let tcp_port = TCP_PORT.clone().fetch_add(1, AtomicOrdering::SeqCst);
let handle = server::run_tcp(addr, communication)?; let addr = format!("127.0.0.1:{}", tcp_port);
let mut client = ssip_client::tcp::Builder::new(addr)?.build()?; let handle = server::run_tcp(&addr, communication)?;
let mut client = ssip_client::tcp::Builder::new(&addr)?.build()?;
client client
.set_client_name(ClientName::new("test", "test"))? .set_client_name(ClientName::new("test", "test"))?
.check_client_name_set()?; .check_client_name_set()?;
@ -69,6 +80,20 @@ where
Ok(()) Ok(())
} }
#[cfg(all(unix, not(feature = "async-mio")))]
macro_rules! test_client {
($communication:expr, $closure:expr) => {
test_unix_client($communication, $closure)
};
}
#[cfg(all(not(unix), not(feature = "async-mio")))]
macro_rules! test_client {
($communication:expr, $closure:expr) => {
test_tcp_client($communication, $closure)
};
}
#[cfg(not(feature = "async-mio"))] #[cfg(not(feature = "async-mio"))]
const SET_CLIENT_COMMUNICATION: (&str, &str) = ( const SET_CLIENT_COMMUNICATION: (&str, &str) = (
"SET self CLIENT_NAME test:test:main\r\n", "SET self CLIENT_NAME test:test:main\r\n",
@ -86,6 +111,7 @@ fn connect_and_quit() -> ClientResult<()> {
client.quit().unwrap().check_status(OK_BYE).unwrap(); client.quit().unwrap().check_status(OK_BYE).unwrap();
Ok(()) Ok(())
} }
#[cfg(unix)]
test_unix_client(&COMMUNICATION, process)?; test_unix_client(&COMMUNICATION, process)?;
test_tcp_client(&COMMUNICATION, process)?; test_tcp_client(&COMMUNICATION, process)?;
Ok(()) Ok(())
@ -94,7 +120,7 @@ fn connect_and_quit() -> ClientResult<()> {
#[test] #[test]
#[cfg(not(feature = "async-mio"))] #[cfg(not(feature = "async-mio"))]
fn say_one_line() -> ClientResult<()> { fn say_one_line() -> ClientResult<()> {
test_unix_client( test_client!(
&[ &[
SET_CLIENT_COMMUNICATION, SET_CLIENT_COMMUNICATION,
("SPEAK\r\n", "230 OK RECEIVING DATA\r\n"), ("SPEAK\r\n", "230 OK RECEIVING DATA\r\n"),
@ -117,7 +143,7 @@ fn say_one_line() -> ClientResult<()> {
.unwrap() .unwrap()
); );
Ok(()) Ok(())
}, }
) )
} }
@ -126,12 +152,12 @@ macro_rules! test_setter {
#[test] #[test]
#[cfg(not(feature = "async-mio"))] #[cfg(not(feature = "async-mio"))]
fn $setter() -> ClientResult<()> { fn $setter() -> ClientResult<()> {
test_unix_client( test_client!(
&[SET_CLIENT_COMMUNICATION, ($question, $answer)], &[SET_CLIENT_COMMUNICATION, ($question, $answer)],
|client| { |client| {
client.$setter($($arg)*).unwrap().check_status($code).unwrap(); client.$setter($($arg)*).unwrap().check_status($code).unwrap();
Ok(()) Ok(())
}, }
) )
} }
}; };
@ -142,13 +168,13 @@ macro_rules! test_getter {
#[test] #[test]
#[cfg(not(feature = "async-mio"))] #[cfg(not(feature = "async-mio"))]
fn $getter() -> ClientResult<()> { fn $getter() -> ClientResult<()> {
test_unix_client( test_client!(
&[SET_CLIENT_COMMUNICATION, ($question, $answer)], &[SET_CLIENT_COMMUNICATION, ($question, $answer)],
|client| { |client| {
let value = client.$getter $get_args.unwrap().$receive $recv_arg.unwrap(); let value = client.$getter $get_args.unwrap().$receive $recv_arg.unwrap();
assert_eq!($value, value); assert_eq!($value, value);
Ok(()) Ok(())
}, }
) )
} }
}; };
@ -165,13 +191,13 @@ macro_rules! test_list {
#[test] #[test]
#[cfg(not(feature = "async-mio"))] #[cfg(not(feature = "async-mio"))]
fn $getter() -> ClientResult<()> { fn $getter() -> ClientResult<()> {
test_unix_client( test_client!(
&[SET_CLIENT_COMMUNICATION, ($question, $answer)], &[SET_CLIENT_COMMUNICATION, ($question, $answer)],
|client| { |client| {
let values = client.$getter().unwrap().receive_lines($code).unwrap(); let values = client.$getter().unwrap().receive_lines($code).unwrap();
assert_eq!($values, values.as_slice()); assert_eq!($values, values.as_slice());
Ok(()) Ok(())
}, }
) )
} }
}; };
@ -188,7 +214,7 @@ test_setter!(
#[test] #[test]
#[cfg(not(feature = "async-mio"))] #[cfg(not(feature = "async-mio"))]
fn set_debug() -> ClientResult<()> { fn set_debug() -> ClientResult<()> {
test_unix_client( test_client!(
&[ &[
SET_CLIENT_COMMUNICATION, SET_CLIENT_COMMUNICATION,
( (
@ -204,7 +230,7 @@ fn set_debug() -> ClientResult<()> {
.unwrap(); .unwrap();
assert_eq!("/run/user/100/speech-dispatcher/log/debug", output); assert_eq!("/run/user/100/speech-dispatcher/log/debug", output);
Ok(()) Ok(())
}, }
) )
} }
@ -364,7 +390,7 @@ test_list!(
#[test] #[test]
#[cfg(not(feature = "async-mio"))] #[cfg(not(feature = "async-mio"))]
fn list_synthesis_voices() -> ClientResult<()> { fn list_synthesis_voices() -> ClientResult<()> {
test_unix_client( test_client!(
&[ &[
SET_CLIENT_COMMUNICATION, SET_CLIENT_COMMUNICATION,
( (
@ -383,14 +409,14 @@ fn list_synthesis_voices() -> ClientResult<()> {
assert_eq!(*expected, *found); assert_eq!(*expected, *found);
} }
Ok(()) Ok(())
}, }
) )
} }
#[test] #[test]
#[cfg(not(feature = "async-mio"))] #[cfg(not(feature = "async-mio"))]
fn receive_notification() -> ClientResult<()> { fn receive_notification() -> ClientResult<()> {
test_unix_client( test_client!(
&[ &[
SET_CLIENT_COMMUNICATION, SET_CLIENT_COMMUNICATION,
("SPEAK\r\n", "230 OK RECEIVING DATA\r\n"), ("SPEAK\r\n", "230 OK RECEIVING DATA\r\n"),
@ -420,14 +446,14 @@ fn receive_notification() -> ClientResult<()> {
Ok(_) => panic!("wrong event"), Ok(_) => panic!("wrong event"),
Err(_) => panic!("error on event"), Err(_) => panic!("error on event"),
} }
}, }
) )
} }
#[test] #[test]
#[cfg(not(feature = "async-mio"))] #[cfg(not(feature = "async-mio"))]
fn history_clients_list() -> ClientResult<()> { fn history_clients_list() -> ClientResult<()> {
test_unix_client( test_client!(
&[ &[
SET_CLIENT_COMMUNICATION, SET_CLIENT_COMMUNICATION,
( (
@ -446,7 +472,7 @@ fn history_clients_list() -> ClientResult<()> {
assert_eq!(*expected, *found); assert_eq!(*expected, *found);
} }
Ok(()) Ok(())
}, }
) )
} }

Loading…
Cancel
Save