I am making a crate which needs to support both the tokio
and async-std
runtime. To do this I use the correct dependency matching the used features flag.
#[allow(unused_imports)]
#[cfg(feature = "tokio")]
use tokio::io::{AsyncReadExt, AsyncWriteExt};
#[allow(unused_imports)]
#[cfg(feature = "async-std")]
use async_std::io::{ReadExt, WriteExt};
Originally I had this code:
self.rt.block_on(async {
writer
.write_all(data_to_write)
.await
.map_err(ureq::Error::Io)?;
writer.flush().await.map_err(ureq::Error::Io)?;
Ok(())
})
This compiles fine using cargo build
, but using cargo clippy --all-features --all-targets
, which needs to work for the CI pipeline I get the following errors:
error[E0034]: multiple applicable items in scope
--> crates/arti-ureq/src/lib.rs:250:18
|
250 | .write_all(data_to_write)
| ^^^^^^^^^ multiple `write_all` found
|
= note: candidate #1 is defined in an impl of the trait `async_std::io::WriteExt` for the type `T`
= note: candidate #2 is defined in an impl of the trait `tokio::io::AsyncWriteExt` for the type `W`
help: disambiguate the method for candidate #1
|
249 | async_std::io::WriteExt::write_all(&mut writer, data_to_write)
|
help: disambiguate the method for candidate #2
|
249 | tokio::io::AsyncWriteExt::write_all(&mut writer, data_to_write)
|
I currently solved it like this:
#[allow(unreachable_code)]
self.rt.block_on(async {
#[cfg(feature = "tokio")] {
tokio::io::AsyncWriteExt::write_all(&mut *writer, data_to_write)
.await
.map_err(ureq::Error::Io)?;
tokio::io::AsyncWriteExt::flush(&mut *writer).await.map_err(ureq::Error::Io)?;
return Ok(());
}
#[cfg(feature = "async-std")] {
async_std::io::WriteExt::write_all(&mut *writer, data_to_write)
.await
.map_err(ureq::Error::Io)?;
async_std::io::WriteExt::flush(&mut *writer).await.map_err(ureq::Error::Io)?;
return Ok(());
}
panic!("Either `tokio` or `async-std` feature must be enabled on arti_ureq.");
})
Is this correct, or is there a better way?