somen_decode/
utf32.rs

1use somen::prelude::*;
2
3// A base decoder
4#[inline]
5fn decode(c: u32) -> Option<char> {
6    char::from_u32(c)
7}
8
9/// A UTF-32 encoded [`u32`] decoder.
10///
11/// # Examples
12/// ```
13/// # futures_executor::block_on(async {
14/// # use somen_decode::utf32;
15/// use somen::prelude::*;
16///
17/// let mut parser = utf32();
18/// let mut stream = stream::from_slice(&[0x41, 0xC5, 0x3042, 0x1F4AF, 0x110000]);
19///
20/// assert_eq!(parser.parse(&mut stream).await, Ok('A'));
21/// assert_eq!(parser.parse(&mut stream).await, Ok('Å'));
22/// assert_eq!(parser.parse(&mut stream).await, Ok('あ'));
23/// assert_eq!(parser.parse(&mut stream).await, Ok('💯'));
24/// assert!(parser.parse(&mut stream).await.is_err());
25/// # });
26/// ```
27pub fn utf32<'a, I>() -> impl Parser<I, Output = char>
28where
29    I: Positioned<Ok = u32> + ?Sized + 'a,
30{
31    is_some(decode).expect("UTF-32 character")
32}
33
34/// A UTF-32 encoded [`u8`] decoder. (big-endian)
35///
36/// # Examples
37/// ```
38/// # futures_executor::block_on(async {
39/// # use somen_decode::utf32_be;
40/// use somen::prelude::*;
41///
42/// let mut parser = utf32_be();
43/// let mut stream = stream::from_slice(
44///     b"\x00\x00\x00\x41\x00\x00\x00\xC5\x00\x00\x30\x42\x00\x01\xF4\xAF\x00\x11\x00\x00",
45/// );
46///
47/// assert_eq!(parser.parse(&mut stream).await, Ok('A'));
48/// assert_eq!(parser.parse(&mut stream).await, Ok('Å'));
49/// assert_eq!(parser.parse(&mut stream).await, Ok('あ'));
50/// assert_eq!(parser.parse(&mut stream).await, Ok('💯'));
51/// assert!(parser.parse(&mut stream).await.is_err());
52/// # });
53/// ```
54pub fn utf32_be<'a, I>() -> impl Parser<I, Output = char>
55where
56    I: Positioned<Ok = u8> + ?Sized + 'a,
57{
58    any()
59        .times(4)
60        .fill(0)
61        .try_map(|b| decode(u32::from_be_bytes(b.unwrap())).ok_or("UTF-32BE character"))
62        .rewindable()
63}
64
65/// A UTF-32 encoded [`u8`] decoder. (little-endian)
66///
67/// # Examples
68/// ```
69/// # futures_executor::block_on(async {
70/// # use somen_decode::utf32_le;
71/// use somen::prelude::*;
72///
73/// let mut parser = utf32_le();
74/// let mut stream = stream::from_slice(
75///     b"\x41\x00\x00\x00\xC5\x00\x00\x00\x42\x30\x00\x00\xAF\xF4\x01\x00\x00\x00\x11\x00"
76/// );
77///
78/// assert_eq!(parser.parse(&mut stream).await, Ok('A'));
79/// assert_eq!(parser.parse(&mut stream).await, Ok('Å'));
80/// assert_eq!(parser.parse(&mut stream).await, Ok('あ'));
81/// assert_eq!(parser.parse(&mut stream).await, Ok('💯'));
82/// assert!(parser.parse(&mut stream).await.is_err());
83/// # });
84/// ```
85pub fn utf32_le<'a, I>() -> impl Parser<I, Output = char>
86where
87    I: Positioned<Ok = u8> + ?Sized + 'a,
88{
89    any()
90        .times(4)
91        .fill(0)
92        .try_map(|b| decode(u32::from_le_bytes(b.unwrap())).ok_or("UTF-32LE character"))
93        .rewindable()
94}