Skip to content

Commit 1cc01e7

Browse files
committed
Clarify UTF-16 decoding errors
1 parent 29e035e commit 1cc01e7

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

library/alloc/src/string.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,15 @@ pub struct FromUtf8Error {
410410
/// ```
411411
#[stable(feature = "rust1", since = "1.0.0")]
412412
#[derive(Debug)]
413-
pub struct FromUtf16Error(());
413+
pub struct FromUtf16Error {
414+
kind: FromUtf16ErrorKind,
415+
}
416+
417+
#[derive(Clone, PartialEq, Eq, Debug)]
418+
enum FromUtf16ErrorKind {
419+
LoneSurrogate,
420+
OddBytes,
421+
}
414422

415423
impl String {
416424
/// Creates a new empty `String`.
@@ -719,7 +727,7 @@ impl String {
719727
if let Ok(c) = c {
720728
ret.push(c);
721729
} else {
722-
return Err(FromUtf16Error(()));
730+
return Err(FromUtf16Error { kind: FromUtf16ErrorKind::LoneSurrogate });
723731
}
724732
}
725733
Ok(ret)
@@ -781,13 +789,13 @@ impl String {
781789
#[unstable(feature = "str_from_utf16_endian", issue = "116258")]
782790
pub fn from_utf16le(v: &[u8]) -> Result<String, FromUtf16Error> {
783791
let (chunks, []) = v.as_chunks::<2>() else {
784-
return Err(FromUtf16Error(()));
792+
return Err(FromUtf16Error { kind: FromUtf16ErrorKind::OddBytes });
785793
};
786794
match (cfg!(target_endian = "little"), unsafe { v.align_to::<u16>() }) {
787795
(true, ([], v, [])) => Self::from_utf16(v),
788796
_ => char::decode_utf16(chunks.iter().copied().map(u16::from_le_bytes))
789797
.collect::<Result<_, _>>()
790-
.map_err(|_| FromUtf16Error(())),
798+
.map_err(|_| FromUtf16Error { kind: FromUtf16ErrorKind::LoneSurrogate }),
791799
}
792800
}
793801

@@ -856,13 +864,13 @@ impl String {
856864
#[unstable(feature = "str_from_utf16_endian", issue = "116258")]
857865
pub fn from_utf16be(v: &[u8]) -> Result<String, FromUtf16Error> {
858866
let (chunks, []) = v.as_chunks::<2>() else {
859-
return Err(FromUtf16Error(()));
867+
return Err(FromUtf16Error { kind: FromUtf16ErrorKind::OddBytes });
860868
};
861869
match (cfg!(target_endian = "big"), unsafe { v.align_to::<u16>() }) {
862870
(true, ([], v, [])) => Self::from_utf16(v),
863871
_ => char::decode_utf16(chunks.iter().copied().map(u16::from_be_bytes))
864872
.collect::<Result<_, _>>()
865-
.map_err(|_| FromUtf16Error(())),
873+
.map_err(|_| FromUtf16Error { kind: FromUtf16ErrorKind::LoneSurrogate }),
866874
}
867875
}
868876

@@ -2319,7 +2327,11 @@ impl fmt::Display for FromUtf8Error {
23192327
#[stable(feature = "rust1", since = "1.0.0")]
23202328
impl fmt::Display for FromUtf16Error {
23212329
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2322-
fmt::Display::fmt("invalid utf-16: lone surrogate found", f)
2330+
match self.kind {
2331+
FromUtf16ErrorKind::LoneSurrogate => "invalid utf-16: lone surrogate found",
2332+
FromUtf16ErrorKind::OddBytes => "invalid utf-16: odd number of bytes",
2333+
}
2334+
.fmt(f)
23232335
}
23242336
}
23252337

0 commit comments

Comments
 (0)