diff --git a/serde/build.rs b/serde/build.rs index c32872b95..604511587 100644 --- a/serde/build.rs +++ b/serde/build.rs @@ -15,6 +15,7 @@ fn main() { if minor >= 77 { println!("cargo:rustc-check-cfg=cfg(no_core_cstr)"); + println!("cargo:rustc-check-cfg=cfg(no_core_net)"); println!("cargo:rustc-check-cfg=cfg(no_core_num_saturating)"); println!("cargo:rustc-check-cfg=cfg(no_core_try_from)"); println!("cargo:rustc-check-cfg=cfg(no_diagnostic_namespace)"); @@ -86,6 +87,12 @@ fn main() { println!("cargo:rustc-cfg=no_core_num_saturating"); } + // Support for core::net stabilized in Rust 1.77. + // https://blog.rust-lang.org/2024/03/21/Rust-1.77.0.html + if minor < 77 { + println!("cargo:rustc-cfg=no_core_net"); + } + // Support for the `#[diagnostic]` tool attribute namespace // https://blog.rust-lang.org/2024/05/02/Rust-1.78.0.html#diagnostic-attributes if minor < 78 { diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 02591d982..c85aa30d0 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -1604,7 +1604,7 @@ macro_rules! parse_ip_impl { }; } -#[cfg(feature = "std")] +#[cfg(any(feature = "std", not(no_core_net)))] macro_rules! variant_identifier { ( $name_kind:ident ($($variant:ident; $bytes:expr; $index:expr),*) @@ -1679,7 +1679,7 @@ macro_rules! variant_identifier { } } -#[cfg(feature = "std")] +#[cfg(any(feature = "std", not(no_core_net)))] macro_rules! deserialize_enum { ( $name:ident $name_kind:ident ($($variant:ident; $bytes:expr; $index:expr),*) @@ -1716,8 +1716,8 @@ macro_rules! deserialize_enum { } } -#[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +#[cfg(any(feature = "std", not(no_core_net)))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", not(no_core_net)))))] impl<'de> Deserialize<'de> for net::IpAddr { fn deserialize(deserializer: D) -> Result where @@ -1737,14 +1737,14 @@ impl<'de> Deserialize<'de> for net::IpAddr { } parse_ip_impl! { - #[cfg(feature = "std")] - #[cfg_attr(docsrs, doc(cfg(feature = "std")))] + #[cfg(any(feature = "std", not(no_core_net)))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", not(no_core_net)))))] net::Ipv4Addr, "IPv4 address", 4 } parse_ip_impl! { - #[cfg(feature = "std")] - #[cfg_attr(docsrs, doc(cfg(feature = "std")))] + #[cfg(any(feature = "std", not(no_core_net)))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", not(no_core_net)))))] net::Ipv6Addr, "IPv6 address", 16 } @@ -1770,8 +1770,8 @@ macro_rules! parse_socket_impl { }; } -#[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +#[cfg(any(feature = "std", not(no_core_net)))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", not(no_core_net)))))] impl<'de> Deserialize<'de> for net::SocketAddr { fn deserialize(deserializer: D) -> Result where @@ -1791,15 +1791,15 @@ impl<'de> Deserialize<'de> for net::SocketAddr { } parse_socket_impl! { - #[cfg(feature = "std")] - #[cfg_attr(docsrs, doc(cfg(feature = "std")))] + #[cfg(any(feature = "std", not(no_core_net)))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", not(no_core_net)))))] net::SocketAddrV4, "IPv4 socket address", |(ip, port)| net::SocketAddrV4::new(ip, port), } parse_socket_impl! { - #[cfg(feature = "std")] - #[cfg_attr(docsrs, doc(cfg(feature = "std")))] + #[cfg(any(feature = "std", not(no_core_net)))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", not(no_core_net)))))] net::SocketAddrV6, "IPv6 socket address", |(ip, port)| net::SocketAddrV6::new(ip, port, 0, 0), } @@ -3160,13 +3160,13 @@ atomic_impl! { AtomicU64 "64" } -#[cfg(feature = "std")] +#[cfg(any(feature = "std", not(no_core_net)))] struct FromStrVisitor { expecting: &'static str, ty: PhantomData, } -#[cfg(feature = "std")] +#[cfg(any(feature = "std", not(no_core_net)))] impl FromStrVisitor { fn new(expecting: &'static str) -> Self { FromStrVisitor { @@ -3176,7 +3176,7 @@ impl FromStrVisitor { } } -#[cfg(feature = "std")] +#[cfg(any(feature = "std", not(no_core_net)))] impl<'de, T> Visitor<'de> for FromStrVisitor where T: str::FromStr, diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index d6b9f5ab4..a87558ec5 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -118,7 +118,6 @@ use crate::lib::*; pub mod value; -mod format; mod ignored_any; mod impls; pub(crate) mod size_hint; @@ -1374,7 +1373,7 @@ pub trait Visitor<'de>: Sized { E: Error, { let mut buf = [0u8; 58]; - let mut writer = format::Buf::new(&mut buf); + let mut writer = crate::format::Buf::new(&mut buf); fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as i128", v)).unwrap(); Err(Error::invalid_type( Unexpected::Other(writer.as_str()), @@ -1436,7 +1435,7 @@ pub trait Visitor<'de>: Sized { E: Error, { let mut buf = [0u8; 57]; - let mut writer = format::Buf::new(&mut buf); + let mut writer = crate::format::Buf::new(&mut buf); fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as u128", v)).unwrap(); Err(Error::invalid_type( Unexpected::Other(writer.as_str()), diff --git a/serde/src/de/format.rs b/serde/src/format.rs similarity index 100% rename from serde/src/de/format.rs rename to serde/src/format.rs diff --git a/serde/src/lib.rs b/serde/src/lib.rs index e9fc96cba..f40f6a60e 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -238,8 +238,13 @@ mod lib { #[cfg(feature = "std")] pub use std::ffi::CString; + #[cfg(all(not(no_core_net), not(feature = "std")))] + pub use self::core::net; #[cfg(feature = "std")] - pub use std::{error, net}; + pub use std::net; + + #[cfg(feature = "std")] + pub use std::error; #[cfg(feature = "std")] pub use std::collections::{HashMap, HashSet}; @@ -305,6 +310,8 @@ mod integer128; pub mod de; pub mod ser; +mod format; + #[doc(inline)] pub use crate::de::{Deserialize, Deserializer}; #[doc(inline)] diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 557b6aa12..235c9cdeb 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -773,28 +773,18 @@ impl Serialize for SystemTime { /// statically known to never have more than a constant `MAX_LEN` bytes. /// /// Panics if the `Display` impl tries to write more than `MAX_LEN` bytes. -#[cfg(feature = "std")] +#[cfg(any(feature = "std", not(no_core_net)))] macro_rules! serialize_display_bounded_length { ($value:expr, $max:expr, $serializer:expr) => {{ let mut buffer = [0u8; $max]; - let remaining_len = { - let mut remaining = &mut buffer[..]; - write!(remaining, "{}", $value).unwrap(); - remaining.len() - }; - let written_len = buffer.len() - remaining_len; - let written = &buffer[..written_len]; - - // write! only provides fmt::Formatter to Display implementations, which - // has methods write_str and write_char but no method to write arbitrary - // bytes. Therefore `written` must be valid UTF-8. - let written_str = str::from_utf8(written).expect("must be valid UTF-8"); - $serializer.serialize_str(written_str) + let mut writer = crate::format::Buf::new(&mut buffer); + write!(&mut writer, "{}", $value).unwrap(); + $serializer.serialize_str(writer.as_str()) }}; } -#[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +#[cfg(any(feature = "std", not(no_core_net)))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", not(no_core_net)))))] impl Serialize for net::IpAddr { fn serialize(&self, serializer: S) -> Result where @@ -818,7 +808,7 @@ impl Serialize for net::IpAddr { } } -#[cfg(feature = "std")] +#[cfg(any(feature = "std", not(no_core_net)))] const DEC_DIGITS_LUT: &[u8] = b"\ 0001020304050607080910111213141516171819\ 2021222324252627282930313233343536373839\ @@ -826,7 +816,7 @@ const DEC_DIGITS_LUT: &[u8] = b"\ 6061626364656667686970717273747576777879\ 8081828384858687888990919293949596979899"; -#[cfg(feature = "std")] +#[cfg(any(feature = "std", not(no_core_net)))] #[inline] fn format_u8(mut n: u8, out: &mut [u8]) -> usize { if n >= 100 { @@ -847,7 +837,7 @@ fn format_u8(mut n: u8, out: &mut [u8]) -> usize { } } -#[cfg(feature = "std")] +#[cfg(any(feature = "std", not(no_core_net)))] #[test] fn test_format_u8() { let mut i = 0u8; @@ -864,8 +854,8 @@ fn test_format_u8() { } } -#[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +#[cfg(any(feature = "std", not(no_core_net)))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", not(no_core_net)))))] impl Serialize for net::Ipv4Addr { fn serialize(&self, serializer: S) -> Result where @@ -889,8 +879,8 @@ impl Serialize for net::Ipv4Addr { } } -#[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +#[cfg(any(feature = "std", not(no_core_net)))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", not(no_core_net)))))] impl Serialize for net::Ipv6Addr { fn serialize(&self, serializer: S) -> Result where @@ -906,8 +896,8 @@ impl Serialize for net::Ipv6Addr { } } -#[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +#[cfg(any(feature = "std", not(no_core_net)))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", not(no_core_net)))))] impl Serialize for net::SocketAddr { fn serialize(&self, serializer: S) -> Result where @@ -931,8 +921,8 @@ impl Serialize for net::SocketAddr { } } -#[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +#[cfg(any(feature = "std", not(no_core_net)))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", not(no_core_net)))))] impl Serialize for net::SocketAddrV4 { fn serialize(&self, serializer: S) -> Result where @@ -948,8 +938,8 @@ impl Serialize for net::SocketAddrV4 { } } -#[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +#[cfg(any(feature = "std", not(no_core_net)))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", not(no_core_net)))))] impl Serialize for net::SocketAddrV6 { fn serialize(&self, serializer: S) -> Result where