1use utf_types::utf8::Ascii;
18use utf_types::utf8::FourByteSequence;
19use utf_types::utf8::ThreeByteSequence;
20use utf_types::utf8::TwoByteSequence;
21
22use crate::Utf8Handler;
23use core::fmt::Formatter;
24
25#[derive(#[automatically_derived]impl ::core::fmt::Debug for Utf8CharsError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "Utf8CharsError")
}
}Debug, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
Utf8CharsError {
}
#[automatically_derived]impl ::core::cmp::PartialEq for Utf8CharsError {
#[inline]
fn eq(&self, other: &Self) -> bool { true }
}PartialEq, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for Utf8CharsError {
}
#[automatically_derived]impl ::core::clone::Clone for Utf8CharsError {
#[inline]
fn clone(&self) -> Self { *self }
}Clone, #[automatically_derived]impl ::core::marker::Copy for Utf8CharsError { }Copy, #[automatically_derived]impl ::core::cmp::Eq for Utf8CharsError { }Eq, #[automatically_derived]impl ::core::hash::Hash for Utf8CharsError {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {}
}Hash)]
27#[non_exhaustive]
28pub struct Utf8CharsError;
29
30impl core::fmt::Display for Utf8CharsError {
31 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> {
32 f.write_fmt(format_args!("byte sequence not well-formed UTF-8"))write!(f, "byte sequence not well-formed UTF-8")
33 }
34}
35
36impl core::error::Error for Utf8CharsError {}
37
38#[derive(#[automatically_derived]impl ::core::fmt::Debug for ErrorReportingHandler {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "ErrorReportingHandler")
}
}Debug, #[automatically_derived]impl ::core::clone::Clone for ErrorReportingHandler {
#[inline]
fn clone(&self) -> Self { ErrorReportingHandler }
}Clone)]
40pub(crate) struct ErrorReportingHandler;
41
42impl ErrorReportingHandler {
43 pub(crate) fn new() -> Self {
44 Self {}
45 }
46}
47
48impl Utf8Handler for ErrorReportingHandler {
49 type Output = Result<char, Utf8CharsError>;
50
51 #[inline(always)]
59 fn single_byte(&self, ascii: Ascii) -> Self::Output {
60 Ok(ascii.to_char())
61 }
62
63 #[inline(always)]
71 fn two_byte(&self, sequence: TwoByteSequence) -> Self::Output {
72 Ok(sequence.to_char())
73 }
74
75 #[inline(always)]
83 fn three_byte(&self, sequence: ThreeByteSequence) -> Self::Output {
84 Ok(sequence.to_char())
85 }
86
87 #[inline(always)]
95 fn four_byte(&self, sequence: FourByteSequence) -> Self::Output {
96 Ok(sequence.to_char())
97 }
98
99 #[inline(always)]
111 fn error(&self) -> Self::Output {
112 Err(Utf8CharsError)
113 }
114}
115
116#[doc =
r" Iterator by `Result<char,Utf8CharsError>` over `&[u8]` that contains"]
#[doc =
r" potentially-invalid UTF-8. There is exactly one `Utf8CharsError` per"]
#[doc = r" each error as defined by the WHATWG Encoding Standard."]
#[doc = r""]
#[doc = r" ```"]
#[doc =
r#" let s = b"a\xFFb\xFF\x80c\xF0\x9F\xA4\xA6\xF0\x9F\xA4\xF0\x9F\xF0d";"#]
#[doc = r" let plain = utf8_iter::Utf8Chars::new(s);"]
#[doc = r" let reporting = utf8_iter::ErrorReportingUtf8Chars::new(s);"]
#[doc = r" assert!(plain.eq(reporting.map(|r| r.unwrap_or('\u{FFFD}'))));"]
#[doc = r" ```"]
pub struct ErrorReportingUtf8Chars<'a> {
inner: crate::Utf8CharsWithHandler<'a, ErrorReportingHandler>,
}
#[automatically_derived]impl<'a> ::core::fmt::Debug for
ErrorReportingUtf8Chars<'a> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"ErrorReportingUtf8Chars inner", &&self.inner)
}
}
impl<'a> ErrorReportingUtf8Chars<'a> {
#[inline(always)]
pub fn new(bytes: &'a [u8]) -> Self {
Self {
inner: crate::Utf8CharsWithHandler::new(bytes,
ErrorReportingHandler::new()),
}
}
#[must_use]
#[inline(always)]
pub fn as_slice(&self) -> &'a [u8] { self.inner.as_slice() }
}
impl<'a> Iterator for ErrorReportingUtf8Chars<'a> {
type Item = Result<char, Utf8CharsError>;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> { self.inner.next() }
#[inline(always)]
fn count(self) -> usize { self.inner.count() }
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
#[inline(always)]
fn last(mut self) -> Option<Self::Item> { self.next_back() }
}
impl<'a> DoubleEndedIterator for ErrorReportingUtf8Chars<'a> {
#[inline(always)]
fn next_back(&mut self) -> Option<Self::Item> { self.inner.next_back() }
}
impl core::iter::FusedIterator for ErrorReportingUtf8Chars<'_> {}
impl<'a> Clone for ErrorReportingUtf8Chars<'a> {
fn clone(&self) -> Self { Self { inner: self.inner.clone() } }
}
#[doc = r" Iterator by `Result<char,Utf8CharsError>` and their indices over"]
#[doc = r" `&[u8]` that contains potentially-invalid UTF-8. See the crate"]
#[doc = r" documentation."]
pub struct ErrorReportingUtf8CharIndices<'a> {
inner: crate::Utf8CharIndicesWithHandler<'a, ErrorReportingHandler>,
}
#[automatically_derived]impl<'a> ::core::fmt::Debug for
ErrorReportingUtf8CharIndices<'a> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"ErrorReportingUtf8CharIndices inner", &&self.inner)
}
}
impl<'a> ErrorReportingUtf8CharIndices<'a> {
#[inline(always)]
pub fn new(bytes: &'a [u8]) -> Self {
Self {
inner: crate::Utf8CharIndicesWithHandler::new(bytes,
ErrorReportingHandler::new()),
}
}
#[inline(always)]
#[must_use]
pub fn as_slice(&self) -> &'a [u8] { self.inner.as_slice() }
#[inline(always)]
#[must_use]
pub fn offset(&self) -> usize { self.inner.offset() }
}
impl<'a> Iterator for ErrorReportingUtf8CharIndices<'a> {
type Item = (usize, Result<char, Utf8CharsError>);
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> { self.inner.next() }
#[inline(always)]
fn count(self) -> usize { self.inner.count() }
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
#[inline(always)]
fn last(mut self) -> Option<Self::Item> { self.next_back() }
}
impl<'a> DoubleEndedIterator for ErrorReportingUtf8CharIndices<'a> {
#[inline(always)]
fn next_back(&mut self) -> Option<Self::Item> { self.inner.next_back() }
}
impl core::iter::FusedIterator for ErrorReportingUtf8CharIndices<'_> {}
impl<'a> Clone for ErrorReportingUtf8CharIndices<'a> {
fn clone(&self) -> Self { Self { inner: self.inner.clone() } }
}crate::macros::named_iterators_from_no_argument_handler!(
117 ErrorReportingHandler,
118 Result<char, Utf8CharsError>,
119 ,
130 ErrorReportingUtf8Chars,
131 ,
135 ErrorReportingUtf8CharIndices,
136);
137
138#[cfg(test)]
139mod tests {
140 use crate::ErrorReportingUtf8Chars;
141
142 #[test]
144 fn test_size() {
145 assert_eq!(
146 core::mem::size_of::<Option<<ErrorReportingUtf8Chars<'_> as Iterator>::Item>>(),
147 core::mem::size_of::<Option<char>>()
148 );
149 }
150
151 #[test]
152 fn test_eq() {
153 let a: <ErrorReportingUtf8Chars<'_> as Iterator>::Item = Ok('a');
154 let a_again: <ErrorReportingUtf8Chars<'_> as Iterator>::Item = Ok('a');
155 assert_eq!(a, a_again);
156 }
157}