From c9c80a1b6cb922bad7fc0c8803781a0a720b93e9 Mon Sep 17 00:00:00 2001 From: Laurent Pelecq Date: Mon, 18 Apr 2022 13:45:14 +0200 Subject: [PATCH] Fix compilation on non-unix platforms --- Cargo.toml | 3 +- examples/async_mio_loop.rs | 17 +++++---- examples/async_popol_loop.rs | 15 +++++--- examples/hello.rs | 11 ++++-- examples/list.rs | 11 ++++-- examples/notifications.rs | 11 ++++-- src/lib.rs | 1 + tests/mio_tests.rs | 2 +- tests/server.rs | 14 +++++--- tests/synchronous_tests.rs | 68 +++++++++++++++++++++++++----------- 10 files changed, 105 insertions(+), 48 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6a43dab..ea0cd5d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ssip-client" -version = "0.8.0" +version = "0.8.1" authors = ["Laurent Pelecq "] edition = "2018" description = "Client API for Speech Dispatcher" @@ -22,6 +22,7 @@ async-mio = ["mio/net", "mio/os-poll"] [dev-dependencies] mio = { version = "0.8", features = ["os-poll", "os-ext"] } +lazy_static = "1" popol = "0.5" tempfile = "3" diff --git a/examples/async_mio_loop.rs b/examples/async_mio_loop.rs index 1a58a91..6bc996c 100644 --- a/examples/async_mio_loop.rs +++ b/examples/async_mio_loop.rs @@ -1,16 +1,16 @@ -#[cfg(feature = "async-mio")] +#[cfg(all(unix, feature = "async-mio"))] use mio::{unix::SourceFd, Events, Interest, Poll, Token}; -#[cfg(feature = "async-mio")] +#[cfg(all(unix, feature = "async-mio"))] use std::{ collections::VecDeque, io::{self, Write}, os::unix::io::AsRawFd, }; -#[cfg(feature = "async-mio")] -use ssip_client::{fifo, QueuedClient, ClientError, ClientName, ClientResult, Request, Response}; +#[cfg(all(unix, feature = "async-mio"))] +use ssip_client::{fifo, ClientError, ClientName, ClientResult, QueuedClient, Request, Response}; -#[cfg(feature = "async-mio")] +#[cfg(all(unix, feature = "async-mio"))] fn main() -> ClientResult<()> { 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() { println!("see hello for an example of synchronous client."); } + +#[cfg(not(unix))] +fn main() { + println!("example only available on unix."); +} diff --git a/examples/async_popol_loop.rs b/examples/async_popol_loop.rs index 699b050..58a6bd2 100644 --- a/examples/async_popol_loop.rs +++ b/examples/async_popol_loop.rs @@ -1,13 +1,13 @@ -#[cfg(not(feature = "async-mio"))] +#[cfg(all(unix, not(feature = "async-mio")))] use std::{ collections::VecDeque, 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}; -#[cfg(not(feature = "async-mio"))] +#[cfg(all(unix, not(feature = "async-mio")))] fn main() -> ClientResult<()> { #[derive(Clone, Eq, PartialEq)] enum SourceKey { @@ -113,7 +113,12 @@ fn main() -> ClientResult<()> { } } -#[cfg(feature = "async-mio")] +#[cfg(all(unix, feature = "async-mio"))] 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."); } diff --git a/examples/hello.rs b/examples/hello.rs index 2af6d10..dcea32f 100644 --- a/examples/hello.rs +++ b/examples/hello.rs @@ -1,7 +1,7 @@ -#[cfg(not(feature = "async-mio"))] +#[cfg(all(unix, not(feature = "async-mio")))] use ssip_client::{fifo, ClientName, ClientResult}; -#[cfg(not(feature = "async-mio"))] +#[cfg(all(unix, not(feature = "async-mio")))] fn main() -> ClientResult<()> { let mut client = fifo::Builder::new().build()?; client @@ -19,7 +19,12 @@ fn main() -> ClientResult<()> { Ok(()) } -#[cfg(feature = "async-mio")] +#[cfg(all(unix, feature = "async-mio"))] fn main() { println!("see async_mio_loop for an example of asynchronous client."); } + +#[cfg(not(unix))] +fn main() { + println!("example only available on unix."); +} diff --git a/examples/list.rs b/examples/list.rs index 9164acc..b5b105d 100644 --- a/examples/list.rs +++ b/examples/list.rs @@ -1,10 +1,10 @@ -#[cfg(not(feature = "async-mio"))] +#[cfg(all(unix, not(feature = "async-mio")))] use ssip_client::{ fifo, ClientName, ClientResult, SynthesisVoice, OK_OUTPUT_MODULES_LIST_SENT, OK_VOICES_LIST_SENT, }; -#[cfg(not(feature = "async-mio"))] +#[cfg(all(unix, not(feature = "async-mio")))] fn main() -> ClientResult<()> { fn voice_to_string(voice: &SynthesisVoice) -> String { match &voice.language { @@ -54,7 +54,12 @@ fn main() -> ClientResult<()> { Ok(()) } -#[cfg(feature = "async-mio")] +#[cfg(all(unix, feature = "async-mio"))] fn main() { println!("asynchronous client not implemented"); } + +#[cfg(not(unix))] +fn main() { + println!("example only available on unix."); +} diff --git a/examples/notifications.rs b/examples/notifications.rs index cbe07fd..766b0ee 100644 --- a/examples/notifications.rs +++ b/examples/notifications.rs @@ -1,9 +1,9 @@ -#[cfg(not(feature = "async-mio"))] +#[cfg(all(unix, not(feature = "async-mio")))] use ssip_client::{ fifo, ClientName, ClientResult, EventType, NotificationType, OK_NOTIFICATION_SET, }; -#[cfg(not(feature = "async-mio"))] +#[cfg(all(unix, not(feature = "async-mio")))] fn main() -> ClientResult<()> { let mut client = fifo::Builder::new().build()?; client @@ -43,7 +43,12 @@ fn main() -> ClientResult<()> { Ok(()) } -#[cfg(feature = "async-mio")] +#[cfg(all(unix, feature = "async-mio"))] fn main() { println!("asynchronous client not implemented"); } + +#[cfg(not(unix))] +fn main() { + println!("example only available on unix."); +} diff --git a/src/lib.rs b/src/lib.rs index 8b3c0a7..a4383ca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,6 +34,7 @@ mod types; pub mod client; pub mod constants; +#[cfg(unix)] pub mod fifo; pub mod net; pub mod tcp; diff --git a/tests/mio_tests.rs b/tests/mio_tests.rs index 1dfc378..88120aa 100644 --- a/tests/mio_tests.rs +++ b/tests/mio_tests.rs @@ -136,7 +136,7 @@ const BASIC_COMMUNICATION: [(&str, &str); 5] = [ ]; #[test] -#[cfg(feature = "async-mio")] +#[cfg(all(unix, feature = "async-mio"))] fn basic_async_unix_communication() -> ClientResult<()> { let socket_dir = tempfile::tempdir()?; let socket_path = socket_dir.path().join("basic_async_communication.socket"); diff --git a/tests/server.rs b/tests/server.rs index 19a0543..576eb5f 100644 --- a/tests/server.rs +++ b/tests/server.rs @@ -7,11 +7,10 @@ // modified, or distributed except according to those terms. use std::io::{self, BufRead, BufReader, BufWriter, Read, Write}; -use std::path::Path; +use std::net::{Shutdown, TcpListener, ToSocketAddrs}; use std::thread; - -use std::net::{TcpListener, ToSocketAddrs}; -use std::os::unix::net::UnixListener; +#[cfg(unix)] +use std::{os::unix::net::UnixListener, path::Path}; /// Split lines on CRLF fn split_lines(lines: &str) -> Vec { @@ -56,10 +55,12 @@ pub trait Server { } /// Server on a named socket. +#[cfg(unix)] pub struct UnixServer { listener: UnixListener, } +#[cfg(unix)] impl UnixServer { /// Create a new server on a named socket. /// @@ -74,6 +75,7 @@ impl UnixServer { } } +#[cfg(unix)] impl Server for UnixServer { fn serve(&mut self, communication: &[(&'static str, &'static str)]) -> io::Result<()> { let (mut stream, _) = self.listener.accept()?; @@ -100,7 +102,8 @@ impl TcpServer { impl Server for TcpServer { fn serve(&mut self, communication: &[(&'static str, &'static str)]) -> io::Result<()> { 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

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