From 7f831225a9343f622a4a6693bda33d48e33e83c3 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 13 Sep 2025 09:55:41 -0700 Subject: [PATCH] Make from_utf8_lossy private --- serde/src/private/mod.rs | 6 +----- serde_core/src/de/impls.rs | 13 ++++++++----- serde_core/src/lib.rs | 26 -------------------------- serde_core/src/private/mod.rs | 3 +++ serde_core/src/private/string.rs | 23 +++++++++++++++++++++++ 5 files changed, 35 insertions(+), 36 deletions(-) create mode 100644 serde_core/src/private/string.rs diff --git a/serde/src/private/mod.rs b/serde/src/private/mod.rs index 7202677d..1d4d494e 100644 --- a/serde/src/private/mod.rs +++ b/serde/src/private/mod.rs @@ -15,11 +15,7 @@ pub use crate::lib::option::Option::{self, None, Some}; pub use crate::lib::ptr; pub use crate::lib::result::Result::{self, Err, Ok}; -pub use self::string::from_utf8_lossy; +pub use serde_core::__private::string::from_utf8_lossy; #[cfg(any(feature = "alloc", feature = "std"))] pub use crate::lib::{ToString, Vec}; - -mod string { - pub use serde_core::from_utf8_lossy; -} diff --git a/serde_core/src/de/impls.rs b/serde_core/src/de/impls.rs index 7f1962ff..4bd7e0f6 100644 --- a/serde_core/src/de/impls.rs +++ b/serde_core/src/de/impls.rs @@ -4,7 +4,7 @@ use crate::de::{ Deserialize, Deserializer, EnumAccess, Error, MapAccess, SeqAccess, Unexpected, VariantAccess, Visitor, }; - +use crate::private; use crate::seed::InPlaceSeed; #[cfg(any(feature = "std", feature = "alloc"))] @@ -2174,7 +2174,7 @@ impl<'de> Deserialize<'de> for Duration { b"secs" => Ok(Field::Secs), b"nanos" => Ok(Field::Nanos), _ => { - let value = crate::lib::from_utf8_lossy(value); + let value = private::string::from_utf8_lossy(value); Err(Error::unknown_field(&*value, FIELDS)) } } @@ -2465,6 +2465,7 @@ mod range { use crate::lib::*; use crate::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor}; + use crate::private; pub const FIELDS: &[&str] = &["start", "end"]; @@ -2510,7 +2511,7 @@ mod range { b"start" => Ok(Field::Start), b"end" => Ok(Field::End), _ => { - let value = crate::lib::from_utf8_lossy(value); + let value = private::string::from_utf8_lossy(value); Err(Error::unknown_field(&*value, FIELDS)) } } @@ -2623,6 +2624,7 @@ mod range_from { use crate::lib::*; use crate::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor}; + use crate::private; pub const FIELDS: &[&str] = &["start"]; @@ -2665,7 +2667,7 @@ mod range_from { match value { b"start" => Ok(Field::Start), _ => { - let value = crate::lib::from_utf8_lossy(value); + let value = private::string::from_utf8_lossy(value); Err(Error::unknown_field(&*value, FIELDS)) } } @@ -2761,6 +2763,7 @@ mod range_to { use crate::lib::*; use crate::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor}; + use crate::private; pub const FIELDS: &[&str] = &["end"]; @@ -2803,7 +2806,7 @@ mod range_to { match value { b"end" => Ok(Field::End), _ => { - let value = crate::lib::from_utf8_lossy(value); + let value = private::string::from_utf8_lossy(value); Err(Error::unknown_field(&*value, FIELDS)) } } diff --git a/serde_core/src/lib.rs b/serde_core/src/lib.rs index e3bc9278..8956e763 100644 --- a/serde_core/src/lib.rs +++ b/serde_core/src/lib.rs @@ -103,7 +103,6 @@ mod lib { pub use self::core::{cmp, mem}; pub use self::core::cell::{Cell, RefCell}; - pub use self::core::cmp::Reverse; pub use self::core::fmt::{self, Debug, Display, Write as FmtWrite}; pub use self::core::marker::PhantomData; @@ -203,27 +202,6 @@ mod lib { #[cfg(not(no_core_num_saturating))] pub use self::core::num::Saturating; - #[cfg(any(feature = "std", feature = "alloc"))] - #[doc(hidden)] - pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<'_, str> { - String::from_utf8_lossy(bytes) - } - - // The generated code calls this like: - // - // let value = &_serde::__private::from_utf8_lossy(bytes); - // Err(_serde::de::Error::unknown_variant(value, VARIANTS)) - // - // so it is okay for the return type to be different from the std case as long - // as the above works. - #[cfg(not(any(feature = "std", feature = "alloc")))] - #[doc(hidden)] - pub fn from_utf8_lossy(bytes: &[u8]) -> &str { - // Three unicode replacement characters if it fails. They look like a - // white-on-black question mark. The user will recognize it as invalid - // UTF-8. - str::from_utf8(bytes).unwrap_or("\u{fffd}\u{fffd}\u{fffd}") - } } // None of this crate's error handling needs the `From::from` error conversion @@ -259,14 +237,10 @@ pub use crate::de::{Deserialize, Deserializer}; #[doc(inline)] pub use crate::ser::{Serialize, Serializer}; -#[doc(hidden)] -pub use lib::from_utf8_lossy; - // Used by generated code. Not public API. #[doc(hidden)] #[path = "private/mod.rs"] pub mod __private; -#[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))] use self::__private as private; #[path = "de/seed.rs"] diff --git a/serde_core/src/private/mod.rs b/serde_core/src/private/mod.rs index c27198ca..f2c8649b 100644 --- a/serde_core/src/private/mod.rs +++ b/serde_core/src/private/mod.rs @@ -1,6 +1,9 @@ #[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))] mod content; +#[doc(hidden)] +pub mod string; + #[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))] #[doc(hidden)] pub use self::content::{Content, ContentVisitor}; diff --git a/serde_core/src/private/string.rs b/serde_core/src/private/string.rs new file mode 100644 index 00000000..c8121a0d --- /dev/null +++ b/serde_core/src/private/string.rs @@ -0,0 +1,23 @@ +use crate::lib::*; + +#[cfg(any(feature = "std", feature = "alloc"))] +#[doc(hidden)] +pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<'_, str> { + String::from_utf8_lossy(bytes) +} + +// The generated code calls this like: +// +// let value = &_serde::__private::from_utf8_lossy(bytes); +// Err(_serde::de::Error::unknown_variant(value, VARIANTS)) +// +// so it is okay for the return type to be different from the std case as long +// as the above works. +#[cfg(not(any(feature = "std", feature = "alloc")))] +#[doc(hidden)] +pub fn from_utf8_lossy(bytes: &[u8]) -> &str { + // Three unicode replacement characters if it fails. They look like a + // white-on-black question mark. The user will recognize it as invalid + // UTF-8. + str::from_utf8(bytes).unwrap_or("\u{fffd}\u{fffd}\u{fffd}") +}