diff --git a/build.rs b/build.rs new file mode 100644 index 000000000..356f97187 --- /dev/null +++ b/build.rs @@ -0,0 +1,10 @@ +use std::env; + +fn main() { + println!("cargo:rustc-check-cfg=cfg(bytes_has_atomic_ptr)"); + + let target_atomics = env::var("CARGO_CFG_TARGET_HAS_ATOMIC").unwrap_or_default(); + if target_atomics.split(',').any(|atomic| atomic == "ptr") { + println!("cargo:rustc-cfg=bytes_has_atomic_ptr"); + } +} diff --git a/src/bytes.rs b/src/bytes.rs index aed4d7cdb..86f06195d 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -11,6 +11,9 @@ use alloc::{ vec::Vec, }; +#[cfg(bytes_has_atomic_ptr)] +use alloc::sync::Arc; + use crate::buf::IntoIter; #[allow(unused)] use crate::loom::sync::atomic::AtomicMut; @@ -1014,6 +1017,13 @@ impl From> for Bytes { } } +#[cfg(bytes_has_atomic_ptr)] +impl From> for Bytes { + fn from(arc: Arc<[u8]>) -> Bytes { + Bytes::from_owner(arc) + } +} + impl From for BytesMut { /// Convert self into `BytesMut`. /// diff --git a/tests/test_bytes.rs b/tests/test_bytes.rs index 5d01b5b82..5615d92d1 100644 --- a/tests/test_bytes.rs +++ b/tests/test_bytes.rs @@ -67,6 +67,18 @@ fn from_slice() { assert_eq!(Vec::from(&b"abcdefgh"[..]), a); } +#[cfg(bytes_has_atomic_ptr)] +#[test] +fn from_arc() { + let source: Arc<[u8]> = Arc::from(&b"abcdefgh"[..]); + let source_ptr = source.as_ptr(); + let bytes = Bytes::from(source.clone()); + drop(source); + + assert_eq!(bytes, b"abcdefgh"[..]); + assert_eq!(bytes.as_ptr(), source_ptr); +} + #[test] fn fmt() { let a = format!("{:?}", Bytes::from(&b"abcdefg"[..]));