webauthn_rp

WebAuthn Level 3 RP library.
git clone https://git.philomathiclife.com/repos/webauthn_rp
Log | Files | Refs | README

custom.rs (5513B)


      1 use super::{AuthTransports, AuthenticatorTransport, CredentialId, CredentialIdErr};
      2 use core::iter::FusedIterator;
      3 impl<'a: 'b, 'b> TryFrom<&'a [u8]> for CredentialId<&'b [u8]> {
      4     type Error = CredentialIdErr;
      5     #[inline]
      6     fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
      7         Self::from_slice(value)
      8     }
      9 }
     10 impl TryFrom<Vec<u8>> for CredentialId<Vec<u8>> {
     11     type Error = CredentialIdErr;
     12     #[inline]
     13     fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
     14         match CredentialId::<&[u8]>::try_from(value.as_slice()) {
     15             Ok(_) => Ok(Self(value)),
     16             Err(e) => Err(e),
     17         }
     18     }
     19 }
     20 /// [`Iterator`] of [`AuthenticatorTransport`]s returned from
     21 /// [`AuthTransports::into_iter`].
     22 #[derive(Debug)]
     23 pub struct AuthTransportIter(AuthTransports);
     24 impl Iterator for AuthTransportIter {
     25     type Item = AuthenticatorTransport;
     26     #[inline]
     27     fn next(&mut self) -> Option<Self::Item> {
     28         let mut nxt = self.0.remove(AuthenticatorTransport::Ble);
     29         if self.0.0 != nxt.0 {
     30             self.0 = nxt;
     31             return Some(AuthenticatorTransport::Ble);
     32         }
     33         nxt = self.0.remove(AuthenticatorTransport::Hybrid);
     34         if self.0.0 != nxt.0 {
     35             self.0 = nxt;
     36             return Some(AuthenticatorTransport::Hybrid);
     37         }
     38         nxt = self.0.remove(AuthenticatorTransport::Internal);
     39         if self.0.0 != nxt.0 {
     40             self.0 = nxt;
     41             return Some(AuthenticatorTransport::Internal);
     42         }
     43         nxt = self.0.remove(AuthenticatorTransport::Nfc);
     44         if self.0.0 != nxt.0 {
     45             self.0 = nxt;
     46             return Some(AuthenticatorTransport::Nfc);
     47         }
     48         nxt = self.0.remove(AuthenticatorTransport::SmartCard);
     49         if self.0.0 != nxt.0 {
     50             self.0 = nxt;
     51             return Some(AuthenticatorTransport::SmartCard);
     52         }
     53         nxt = self.0.remove(AuthenticatorTransport::Usb);
     54         if self.0.0 == nxt.0 {
     55             None
     56         } else {
     57             self.0 = nxt;
     58             Some(AuthenticatorTransport::Usb)
     59         }
     60     }
     61     #[inline]
     62     fn size_hint(&self) -> (usize, Option<usize>) {
     63         let count = self.len();
     64         (count, Some(count))
     65     }
     66     #[inline]
     67     fn count(self) -> usize
     68     where
     69         Self: Sized,
     70     {
     71         self.len()
     72     }
     73     #[inline]
     74     fn last(mut self) -> Option<Self::Item>
     75     where
     76         Self: Sized,
     77     {
     78         self.next_back()
     79     }
     80 }
     81 impl ExactSizeIterator for AuthTransportIter {
     82     #[expect(clippy::as_conversions, reason = "comment justifies correctness")]
     83     #[inline]
     84     fn len(&self) -> usize {
     85         // Maximum count is 6, so this is fine.
     86         self.0.count() as usize
     87     }
     88 }
     89 impl DoubleEndedIterator for AuthTransportIter {
     90     #[inline]
     91     fn next_back(&mut self) -> Option<Self::Item> {
     92         let mut nxt = self.0.remove(AuthenticatorTransport::Usb);
     93         if self.0.0 != nxt.0 {
     94             self.0 = nxt;
     95             return Some(AuthenticatorTransport::Usb);
     96         }
     97         nxt = self.0.remove(AuthenticatorTransport::SmartCard);
     98         if self.0.0 != nxt.0 {
     99             self.0 = nxt;
    100             return Some(AuthenticatorTransport::SmartCard);
    101         }
    102         nxt = self.0.remove(AuthenticatorTransport::Nfc);
    103         if self.0.0 != nxt.0 {
    104             self.0 = nxt;
    105             return Some(AuthenticatorTransport::Nfc);
    106         }
    107         nxt = self.0.remove(AuthenticatorTransport::Internal);
    108         if self.0.0 != nxt.0 {
    109             self.0 = nxt;
    110             return Some(AuthenticatorTransport::Internal);
    111         }
    112         nxt = self.0.remove(AuthenticatorTransport::Hybrid);
    113         if self.0.0 != nxt.0 {
    114             self.0 = nxt;
    115             return Some(AuthenticatorTransport::Hybrid);
    116         }
    117         nxt = self.0.remove(AuthenticatorTransport::Ble);
    118         if self.0.0 == nxt.0 {
    119             None
    120         } else {
    121             self.0 = nxt;
    122             Some(AuthenticatorTransport::Ble)
    123         }
    124     }
    125 }
    126 impl FusedIterator for AuthTransportIter {}
    127 impl IntoIterator for AuthTransports {
    128     type Item = AuthenticatorTransport;
    129     type IntoIter = AuthTransportIter;
    130     #[inline]
    131     fn into_iter(self) -> Self::IntoIter {
    132         AuthTransportIter(self)
    133     }
    134 }
    135 #[cfg(test)]
    136 mod tests {
    137     use super::{AuthTransports, AuthenticatorTransport};
    138     #[test]
    139     fn iter_all() {
    140         let mut iter = AuthTransports::ALL.into_iter();
    141         assert_eq!(iter.len(), 6);
    142         assert!(
    143             iter.next()
    144                 .map_or(false, |tran| matches!(tran, AuthenticatorTransport::Ble))
    145         );
    146         assert_eq!(iter.len(), 5);
    147         assert!(
    148             iter.next()
    149                 .map_or(false, |tran| matches!(tran, AuthenticatorTransport::Hybrid))
    150         );
    151         assert_eq!(iter.len(), 4);
    152         assert!(
    153             iter.next_back()
    154                 .map_or(false, |tran| matches!(tran, AuthenticatorTransport::Usb))
    155         );
    156         assert_eq!(iter.len(), 3);
    157         assert!(iter.next().map_or(false, |tran| matches!(
    158             tran,
    159             AuthenticatorTransport::Internal
    160         )));
    161         assert_eq!(iter.len(), 2);
    162         assert!(iter.next_back().map_or(false, |tran| matches!(
    163             tran,
    164             AuthenticatorTransport::SmartCard
    165         )));
    166         assert_eq!(iter.len(), 1);
    167         assert!(
    168             iter.next()
    169                 .map_or(false, |tran| matches!(tran, AuthenticatorTransport::Nfc))
    170         );
    171         assert_eq!(iter.len(), 0);
    172         assert!(iter.next().is_none());
    173     }
    174 }