qubit_io/traits/async_char_input.rs
1// =============================================================================
2// Copyright (c) 2026 Haixing Hu.
3//
4// SPDX-License-Identifier: Apache-2.0
5//
6// Licensed under the Apache License, Version 2.0.
7// =============================================================================
8
9use crate::AsyncInput;
10
11/// An asynchronous input whose items are Unicode scalar values.
12///
13/// This trait adds no methods. Every [`AsyncInput<Item = char>`](AsyncInput),
14/// including unsized streams, implements it automatically. Implement
15/// [`AsyncInput`] to provide the operations; no separate implementation of
16/// `AsyncCharInput` is needed.
17///
18/// Character counts measure Unicode scalar values, not encoded bytes or
19/// grapheme clusters. This trait does not encode or decode text.
20///
21/// The inherited polling methods retain their pinning and readiness contracts;
22/// implementors do not need to be `Unpin`.
23///
24/// # Examples
25///
26/// ```
27/// use std::io;
28/// use std::pin::Pin;
29/// use std::task::{Context, Poll};
30/// use qubit_io::AsyncCharInput;
31///
32/// fn read<S: AsyncCharInput + ?Sized>(
33/// stream: Pin<&mut S>, cx: &mut Context<'_>, output: &mut [char],
34/// ) -> Poll<io::Result<usize>> {
35/// stream.poll_read(cx, output)
36/// }
37/// ```
38///
39/// Streams with a different item type do not satisfy this bound:
40///
41/// ```compile_fail
42/// use qubit_io::{AsyncInput, AsyncCharInput};
43///
44/// fn accept(stream: impl AsyncCharInput) {}
45///
46/// fn reject(stream: impl AsyncInput<Item = u8>) {
47/// accept(stream);
48/// }
49/// ```
50pub trait AsyncCharInput: AsyncInput<Item = char> {}
51
52impl<T: AsyncInput<Item = char> + ?Sized> AsyncCharInput for T {}