Skip to content

Commit c3ad79c

Browse files
authored
Merge pull request #116 from kevinmehall/refactor
Refactor
2 parents dad53d2 + 5e866af commit c3ad79c

File tree

13 files changed

+531
-386
lines changed

13 files changed

+531
-386
lines changed

src/descriptors.rs

Lines changed: 147 additions & 147 deletions
Large diffs are not rendered by default.

src/device.rs

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ use crate::{
55
},
66
platform,
77
transfer::{
8-
Control, ControlIn, ControlOut, EndpointType, Queue, RequestBuffer, TransferError,
9-
TransferFuture,
8+
Control, ControlIn, ControlOut, Queue, RequestBuffer, TransferError, TransferFuture,
9+
TransferType,
1010
},
1111
DeviceInfo, Error, MaybeFuture, Speed,
1212
};
1313
use log::error;
14-
use std::{io::ErrorKind, sync::Arc, time::Duration};
14+
use std::{io::ErrorKind, num::NonZeroU8, sync::Arc, time::Duration};
1515

1616
/// An opened USB device.
1717
///
@@ -46,21 +46,24 @@ impl Device {
4646
pub(crate) fn open(
4747
d: &DeviceInfo,
4848
) -> impl MaybeFuture<Output = Result<Device, std::io::Error>> {
49-
platform::Device::from_device_info(d)
49+
platform::Device::from_device_info(d).map(|d| d.map(Device::wrap))
5050
}
5151

5252
/// Wraps a device that is already open.
5353
#[cfg(any(target_os = "android", target_os = "linux"))]
5454
pub fn from_fd(fd: std::os::fd::OwnedFd) -> impl MaybeFuture<Output = Result<Device, Error>> {
55-
platform::Device::from_fd(fd)
55+
platform::Device::from_fd(fd).map(|d| d.map(Device::wrap))
5656
}
5757

5858
/// Open an interface of the device and claim it for exclusive use.
5959
pub fn claim_interface(
6060
&self,
6161
interface: u8,
6262
) -> impl MaybeFuture<Output = Result<Interface, Error>> {
63-
self.backend.clone().claim_interface(interface)
63+
self.backend
64+
.clone()
65+
.claim_interface(interface)
66+
.map(|i| i.map(Interface::wrap))
6467
}
6568

6669
/// Detach kernel drivers and open an interface of the device and claim it for exclusive use.
@@ -72,7 +75,10 @@ impl Device {
7275
&self,
7376
interface: u8,
7477
) -> impl MaybeFuture<Output = Result<Interface, Error>> {
75-
self.backend.clone().detach_and_claim_interface(interface)
78+
self.backend
79+
.clone()
80+
.detach_and_claim_interface(interface)
81+
.map(|i| i.map(Interface::wrap))
7682
}
7783

7884
/// Detach kernel drivers for the specified interface.
@@ -134,9 +140,7 @@ impl Device {
134140
///
135141
/// This returns cached data and does not perform IO.
136142
pub fn configurations(&self) -> impl Iterator<Item = ConfigurationDescriptor> {
137-
self.backend
138-
.configuration_descriptors()
139-
.map(ConfigurationDescriptor::new)
143+
self.backend.configuration_descriptors()
140144
}
141145

142146
/// Set the device configuration.
@@ -237,17 +241,16 @@ impl Device {
237241
/// See notes on [`get_descriptor`][`Self::get_descriptor`].
238242
pub fn get_string_descriptor(
239243
&self,
240-
desc_index: u8,
244+
desc_index: NonZeroU8,
241245
language_id: u16,
242246
timeout: Duration,
243247
) -> Result<String, Error> {
244-
if desc_index == 0 {
245-
return Err(Error::new(
246-
ErrorKind::InvalidInput,
247-
"string descriptor index 0 is reserved for the language table",
248-
));
249-
}
250-
let data = self.get_descriptor(DESCRIPTOR_TYPE_STRING, desc_index, language_id, timeout)?;
248+
let data = self.get_descriptor(
249+
DESCRIPTOR_TYPE_STRING,
250+
desc_index.get(),
251+
language_id,
252+
timeout,
253+
)?;
251254

252255
decode_string_descriptor(&data)
253256
.map_err(|_| Error::new(ErrorKind::InvalidData, "string descriptor data was invalid"))
@@ -394,6 +397,11 @@ impl Interface {
394397
self.backend.clone().set_alt_setting(alt_setting)
395398
}
396399

400+
/// Get the current alternate setting of this interface.
401+
pub fn get_alt_setting(&self) -> u8 {
402+
self.backend.get_alt_setting()
403+
}
404+
397405
/// Synchronously perform a single **IN (device-to-host)** transfer on the default **control** endpoint.
398406
///
399407
/// ### Platform-specific notes
@@ -465,7 +473,7 @@ impl Interface {
465473
/// least significant byte differs from the interface number, and this may
466474
/// become an error in the future.
467475
pub fn control_in(&self, data: ControlIn) -> TransferFuture<ControlIn> {
468-
let mut t = self.backend.make_transfer(0, EndpointType::Control);
476+
let mut t = self.backend.make_transfer(0, TransferType::Control);
469477
t.submit::<ControlIn>(data);
470478
TransferFuture::new(t)
471479
}
@@ -501,7 +509,7 @@ impl Interface {
501509
/// least significant byte differs from the interface number, and this may
502510
/// become an error in the future.
503511
pub fn control_out(&self, data: ControlOut) -> TransferFuture<ControlOut> {
504-
let mut t = self.backend.make_transfer(0, EndpointType::Control);
512+
let mut t = self.backend.make_transfer(0, TransferType::Control);
505513
t.submit::<ControlOut>(data);
506514
TransferFuture::new(t)
507515
}
@@ -511,7 +519,7 @@ impl Interface {
511519
/// * The requested length must be a multiple of the endpoint's maximum packet size
512520
/// * An IN endpoint address must have the top (`0x80`) bit set.
513521
pub fn bulk_in(&self, endpoint: u8, buf: RequestBuffer) -> TransferFuture<RequestBuffer> {
514-
let mut t = self.backend.make_transfer(endpoint, EndpointType::Bulk);
522+
let mut t = self.backend.make_transfer(endpoint, TransferType::Bulk);
515523
t.submit(buf);
516524
TransferFuture::new(t)
517525
}
@@ -520,7 +528,7 @@ impl Interface {
520528
///
521529
/// * An OUT endpoint address must have the top (`0x80`) bit clear.
522530
pub fn bulk_out(&self, endpoint: u8, buf: Vec<u8>) -> TransferFuture<Vec<u8>> {
523-
let mut t = self.backend.make_transfer(endpoint, EndpointType::Bulk);
531+
let mut t = self.backend.make_transfer(endpoint, TransferType::Bulk);
524532
t.submit(buf);
525533
TransferFuture::new(t)
526534
}
@@ -529,14 +537,14 @@ impl Interface {
529537
///
530538
/// * An IN endpoint address must have the top (`0x80`) bit set.
531539
pub fn bulk_in_queue(&self, endpoint: u8) -> Queue<RequestBuffer> {
532-
Queue::new(self.backend.clone(), endpoint, EndpointType::Bulk)
540+
Queue::new(self.backend.clone(), endpoint, TransferType::Bulk)
533541
}
534542

535543
/// Create a queue for managing multiple **OUT (host-to-device)** transfers on a **bulk** endpoint.
536544
///
537545
/// * An OUT endpoint address must have the top (`0x80`) bit clear.
538546
pub fn bulk_out_queue(&self, endpoint: u8) -> Queue<Vec<u8>> {
539-
Queue::new(self.backend.clone(), endpoint, EndpointType::Bulk)
547+
Queue::new(self.backend.clone(), endpoint, TransferType::Bulk)
540548
}
541549

542550
/// Submit a single **IN (device-to-host)** transfer on the specified **interrupt** endpoint.
@@ -546,7 +554,7 @@ impl Interface {
546554
pub fn interrupt_in(&self, endpoint: u8, buf: RequestBuffer) -> TransferFuture<RequestBuffer> {
547555
let mut t = self
548556
.backend
549-
.make_transfer(endpoint, EndpointType::Interrupt);
557+
.make_transfer(endpoint, TransferType::Interrupt);
550558
t.submit(buf);
551559
TransferFuture::new(t)
552560
}
@@ -557,7 +565,7 @@ impl Interface {
557565
pub fn interrupt_out(&self, endpoint: u8, buf: Vec<u8>) -> TransferFuture<Vec<u8>> {
558566
let mut t = self
559567
.backend
560-
.make_transfer(endpoint, EndpointType::Interrupt);
568+
.make_transfer(endpoint, TransferType::Interrupt);
561569
t.submit(buf);
562570
TransferFuture::new(t)
563571
}
@@ -566,14 +574,14 @@ impl Interface {
566574
///
567575
/// * An IN endpoint address must have the top (`0x80`) bit set.
568576
pub fn interrupt_in_queue(&self, endpoint: u8) -> Queue<RequestBuffer> {
569-
Queue::new(self.backend.clone(), endpoint, EndpointType::Interrupt)
577+
Queue::new(self.backend.clone(), endpoint, TransferType::Interrupt)
570578
}
571579

572580
/// Create a queue for managing multiple **OUT (device-to-host)** transfers on an **interrupt** endpoint.
573581
///
574582
/// * An OUT endpoint address must have the top (`0x80`) bit clear.
575583
pub fn interrupt_out_queue(&self, endpoint: u8) -> Queue<Vec<u8>> {
576-
Queue::new(self.backend.clone(), endpoint, EndpointType::Interrupt)
584+
Queue::new(self.backend.clone(), endpoint, TransferType::Interrupt)
577585
}
578586

579587
/// Clear a bulk or interrupt endpoint's halt / stall condition.
@@ -605,14 +613,19 @@ impl Interface {
605613
.backend
606614
.device
607615
.configuration_descriptors()
608-
.map(ConfigurationDescriptor::new)
609616
.find(|c| c.configuration_value() == active);
610617

611618
configuration
612619
.into_iter()
613620
.flat_map(|i| i.interface_alt_settings())
614621
.filter(|g| g.interface_number() == self.backend.interface_number)
615622
}
623+
624+
/// Get the interface descriptor for the current alternate setting.
625+
pub fn descriptor(&self) -> Option<InterfaceDescriptor> {
626+
self.descriptors()
627+
.find(|i| i.alternate_setting() == self.get_alt_setting())
628+
}
616629
}
617630

618631
#[test]

src/maybe_future.rs

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
use std::future::IntoFuture;
1+
use std::{
2+
future::{Future, IntoFuture},
3+
pin::Pin,
4+
task::{Context, Poll},
5+
};
26

37
/// IO that may be performed synchronously or asynchronously.
48
///
@@ -8,6 +12,17 @@ pub trait MaybeFuture: IntoFuture {
812
/// Block waiting for the action to complete
913
#[cfg(not(target_arch = "wasm32"))]
1014
fn wait(self) -> Self::Output;
15+
16+
/// Apply a function to the output.
17+
fn map<T: FnOnce(Self::Output) -> R + Unpin, R>(self, f: T) -> Map<Self, T>
18+
where
19+
Self: Sized,
20+
{
21+
Map {
22+
wrapped: self,
23+
func: f,
24+
}
25+
}
1126
}
1227

1328
#[cfg(any(
@@ -73,3 +88,47 @@ impl<T> MaybeFuture for Ready<T> {
7388
self.0
7489
}
7590
}
91+
92+
pub struct Map<F, T> {
93+
wrapped: F,
94+
func: T,
95+
}
96+
97+
impl<F: MaybeFuture, T: FnOnce(F::Output) -> R, R> IntoFuture for Map<F, T> {
98+
type Output = R;
99+
type IntoFuture = MapFut<F::IntoFuture, T>;
100+
101+
fn into_future(self) -> Self::IntoFuture {
102+
MapFut {
103+
wrapped: self.wrapped.into_future(),
104+
func: Some(self.func),
105+
}
106+
}
107+
}
108+
109+
impl<F: MaybeFuture, T: FnOnce(F::Output) -> R, R> MaybeFuture for Map<F, T> {
110+
fn wait(self) -> Self::Output {
111+
(self.func)(self.wrapped.wait())
112+
}
113+
}
114+
115+
pub struct MapFut<F, T> {
116+
wrapped: F,
117+
func: Option<T>,
118+
}
119+
120+
impl<F: Future, T: FnOnce(F::Output) -> R, R> Future for MapFut<F, T> {
121+
type Output = R;
122+
123+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
124+
// SAFETY: structural pin projection: `self.wrapped` is always pinned.
125+
let wrapped = unsafe { self.as_mut().map_unchecked_mut(|s| &mut s.wrapped) };
126+
127+
Future::poll(wrapped, cx).map(|output| {
128+
// SAFETY: `self.func` is never pinned.
129+
let func = unsafe { &mut self.as_mut().get_unchecked_mut().func };
130+
131+
(func.take().expect("polled after completion"))(output)
132+
})
133+
}
134+
}

0 commit comments

Comments
 (0)