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 }