use std::fmt;
use super::DriverName;
pub const CLAIM_FLAG_NONE: u8 = 0x00;
pub const CLAIM_FLAG_IF_DRIVER: u8 = 0x01;
pub const CLAIM_FLAG_EXCEPT_DRIVER: u8 = 0x02;
#[repr(u8)]
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub enum UsbfsDisconnectClaimFlag {
None = CLAIM_FLAG_NONE,
#[default]
IfDriver = CLAIM_FLAG_IF_DRIVER,
ExceptDriver = CLAIM_FLAG_EXCEPT_DRIVER,
}
impl UsbfsDisconnectClaimFlag {
pub const fn new() -> Self {
Self::IfDriver
}
pub const fn create(val: u8) -> Self {
match val {
CLAIM_FLAG_IF_DRIVER => Self::IfDriver,
CLAIM_FLAG_EXCEPT_DRIVER => Self::ExceptDriver,
_ => Self::None,
}
}
pub const fn inner(&self) -> u8 {
*self as u8
}
pub fn into_inner(self) -> u8 {
self as u8
}
}
impl From<&UsbfsDisconnectClaimFlag> for &'static str {
fn from(val: &UsbfsDisconnectClaimFlag) -> Self {
match val {
UsbfsDisconnectClaimFlag::None => "no driver",
UsbfsDisconnectClaimFlag::IfDriver => "IF driver",
UsbfsDisconnectClaimFlag::ExceptDriver => "except driver",
}
}
}
impl From<u8> for UsbfsDisconnectClaimFlag {
fn from(val: u8) -> Self {
Self::create(val)
}
}
impl From<&UsbfsDisconnectClaimFlag> for u8 {
fn from(val: &UsbfsDisconnectClaimFlag) -> Self {
val.inner()
}
}
impl From<UsbfsDisconnectClaimFlag> for u8 {
fn from(val: UsbfsDisconnectClaimFlag) -> Self {
val.into_inner()
}
}
impl fmt::Display for UsbfsDisconnectClaimFlag {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, r#""{}""#, <&str>::from(self))
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct UsbfsDisconnectClaim {
interface: u32,
flags: UsbfsDisconnectClaimFlag,
driver: DriverName,
}
impl UsbfsDisconnectClaim {
pub const fn new() -> Self {
Self {
interface: 0,
flags: UsbfsDisconnectClaimFlag::new(),
driver: DriverName::new(),
}
}
pub fn create(interface: u32, flags: UsbfsDisconnectClaimFlag, driver: &str) -> Self {
Self {
interface,
flags,
driver: driver.into(),
}
}
pub const fn interface(&self) -> u32 {
self.interface
}
pub fn set_interface(&mut self, iface: u32) {
self.interface = iface;
}
pub fn with_interface(mut self, iface: u32) -> Self {
self.set_interface(iface);
self
}
pub const fn flags(&self) -> UsbfsDisconnectClaimFlag {
self.flags
}
pub fn set_flags(&mut self, flags: UsbfsDisconnectClaimFlag) {
self.flags = flags;
}
pub fn with_flags(mut self, flags: UsbfsDisconnectClaimFlag) -> Self {
self.set_flags(flags);
self
}
pub fn driver(&self) -> &str {
self.driver.as_str()
}
pub fn set_driver(&mut self, driver: &str) {
self.driver.from_string(driver);
}
pub fn with_driver(mut self, driver: &str) -> Self {
self.set_driver(driver);
self
}
}
impl Default for UsbfsDisconnectClaim {
fn default() -> Self {
Self::new()
}
}
impl fmt::Display for UsbfsDisconnectClaim {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{{")?;
write!(f, r#""interface": {}, "#, self.interface)?;
write!(f, r#""flags": {}, "#, self.flags)?;
write!(f, r#""driver": "{}""#, self.driver())?;
write!(f, "}}")
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::USBFS_MAX_DRIVER_NAME;
#[test]
fn test_usbfs_disconnect_claim_flag() {
assert_eq!(CLAIM_FLAG_NONE, UsbfsDisconnectClaimFlag::None.inner());
assert_eq!(
CLAIM_FLAG_IF_DRIVER,
UsbfsDisconnectClaimFlag::IfDriver.inner()
);
assert_eq!(
CLAIM_FLAG_EXCEPT_DRIVER,
UsbfsDisconnectClaimFlag::ExceptDriver.inner()
);
assert_eq!(
UsbfsDisconnectClaimFlag::from(CLAIM_FLAG_NONE),
UsbfsDisconnectClaimFlag::None
);
assert_eq!(
UsbfsDisconnectClaimFlag::from(CLAIM_FLAG_IF_DRIVER),
UsbfsDisconnectClaimFlag::IfDriver
);
assert_eq!(
UsbfsDisconnectClaimFlag::from(CLAIM_FLAG_EXCEPT_DRIVER),
UsbfsDisconnectClaimFlag::ExceptDriver
);
}
#[test]
fn test_usbfs_disconnect_claim() {
let mut null_claim = UsbfsDisconnectClaim::new();
let exp_interface = 1;
let exp_flag = UsbfsDisconnectClaimFlag::ExceptDriver;
let exp_driver = "test_driver";
let exp_claim = UsbfsDisconnectClaim::create(exp_interface, exp_flag, exp_driver);
assert_eq!(null_claim.interface(), 0);
assert_eq!(null_claim.flags(), UsbfsDisconnectClaimFlag::new());
assert_eq!(null_claim.driver(), "");
null_claim.set_interface(exp_interface);
assert_eq!(null_claim.interface(), exp_interface);
null_claim.set_flags(exp_flag);
assert_eq!(null_claim.flags(), exp_flag);
null_claim.set_driver(exp_driver);
assert_eq!(null_claim.driver(), exp_driver);
assert_eq!(exp_claim.interface(), exp_interface);
assert_eq!(exp_claim.flags(), exp_flag);
assert_eq!(exp_claim.driver(), exp_driver);
assert_eq!(
UsbfsDisconnectClaim::new()
.with_interface(exp_interface)
.interface(),
exp_interface
);
assert_eq!(
UsbfsDisconnectClaim::new().with_flags(exp_flag).flags(),
exp_flag
);
assert_eq!(
UsbfsDisconnectClaim::new().with_driver(exp_driver).driver(),
exp_driver
);
let over_max_driver = "a".repeat(USBFS_MAX_DRIVER_NAME + 2);
let max_claim = UsbfsDisconnectClaim::new().with_driver(over_max_driver.as_str());
assert_eq!(
max_claim.driver(),
&over_max_driver[..USBFS_MAX_DRIVER_NAME]
);
assert_eq!(max_claim.driver().len(), USBFS_MAX_DRIVER_NAME);
}
}