1use std::{
7 fmt::Display,
8 future::Future,
9 io,
10 marker::PhantomData,
11 task::{Context, Poll},
12};
13
14use crate::platform;
15
16mod queue;
17pub use queue::Queue;
18
19mod buffer;
20pub use buffer::{RequestBuffer, ResponseBuffer};
21
22mod control;
23#[allow(unused)]
24pub(crate) use control::SETUP_PACKET_SIZE;
25pub use control::{Control, ControlIn, ControlOut, ControlType, Direction, Recipient};
26
27mod internal;
28pub(crate) use internal::{
29 notify_completion, PlatformSubmit, PlatformTransfer, TransferHandle, TransferRequest,
30};
31
32#[derive(Debug, Copy, Clone, PartialEq, Eq)]
34#[allow(dead_code)]
35pub enum EndpointType {
36 Control = 0,
38
39 Isochronous = 1,
41
42 Bulk = 2,
44
45 Interrupt = 3,
47}
48
49#[derive(Debug, Copy, Clone, PartialEq, Eq)]
51pub enum TransferError {
52 Cancelled,
54
55 Stall,
63
64 Disconnected,
66
67 Fault,
69
70 Unknown,
72}
73
74impl Display for TransferError {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 match self {
77 TransferError::Cancelled => write!(f, "transfer was cancelled"),
78 TransferError::Stall => write!(f, "endpoint STALL condition"),
79 TransferError::Disconnected => write!(f, "device disconnected"),
80 TransferError::Fault => write!(f, "hardware fault or protocol violation"),
81 TransferError::Unknown => write!(f, "unknown error"),
82 }
83 }
84}
85
86impl std::error::Error for TransferError {}
87
88impl From<TransferError> for io::Error {
89 fn from(value: TransferError) -> Self {
90 match value {
91 TransferError::Cancelled => io::Error::new(io::ErrorKind::Interrupted, value),
92 TransferError::Stall => io::Error::new(io::ErrorKind::ConnectionReset, value),
93 TransferError::Disconnected => io::Error::new(io::ErrorKind::ConnectionAborted, value),
94 TransferError::Fault => io::Error::new(io::ErrorKind::Other, value),
95 TransferError::Unknown => io::Error::new(io::ErrorKind::Other, value),
96 }
97 }
98}
99
100#[derive(Debug, Clone)]
107#[must_use]
108pub struct Completion<T> {
109 pub data: T,
111
112 pub status: Result<(), TransferError>,
114}
115
116impl<T> Completion<T> {
117 pub fn into_result(self) -> Result<T, TransferError> {
121 self.status.map(|()| self.data)
122 }
123}
124
125impl TryFrom<Completion<Vec<u8>>> for Vec<u8> {
126 type Error = TransferError;
127
128 fn try_from(c: Completion<Vec<u8>>) -> Result<Self, Self::Error> {
129 c.into_result()
130 }
131}
132
133impl TryFrom<Completion<ResponseBuffer>> for ResponseBuffer {
134 type Error = TransferError;
135
136 fn try_from(c: Completion<ResponseBuffer>) -> Result<Self, Self::Error> {
137 c.into_result()
138 }
139}
140
141pub struct TransferFuture<D: TransferRequest> {
155 transfer: TransferHandle<platform::TransferData>,
156 ty: PhantomData<D::Response>,
157}
158
159impl<D: TransferRequest> TransferFuture<D> {
160 pub(crate) fn new(transfer: TransferHandle<platform::TransferData>) -> TransferFuture<D> {
161 TransferFuture {
162 transfer,
163 ty: PhantomData,
164 }
165 }
166}
167
168impl<D: TransferRequest> Future for TransferFuture<D>
169where
170 platform::TransferData: PlatformSubmit<D>,
171 D::Response: Unpin,
172{
173 type Output = Completion<D::Response>;
174
175 fn poll(mut self: std::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
176 self.as_mut().transfer.poll_completion::<D>(cx)
177 }
178}