version.rs (4151B)
1 use crate::error::RadrootsSimplexSmpProtoError; 2 use alloc::string::{String, ToString}; 3 use core::fmt; 4 use core::str::FromStr; 5 6 pub const RADROOTS_SIMPLEX_SMP_INITIAL_CLIENT_VERSION: u16 = 1; 7 pub const RADROOTS_SIMPLEX_SMP_SERVER_HOSTNAMES_CLIENT_VERSION: u16 = 2; 8 pub const RADROOTS_SIMPLEX_SMP_SENDER_AUTH_KEY_CLIENT_VERSION: u16 = 3; 9 pub const RADROOTS_SIMPLEX_SMP_SHORT_LINKS_CLIENT_VERSION: u16 = 4; 10 pub const RADROOTS_SIMPLEX_SMP_CURRENT_CLIENT_VERSION: u16 = 11 RADROOTS_SIMPLEX_SMP_SHORT_LINKS_CLIENT_VERSION; 12 pub const RADROOTS_SIMPLEX_SMP_INITIAL_TRANSPORT_VERSION: u16 = 6; 13 pub const RADROOTS_SIMPLEX_SMP_AUTH_COMMANDS_TRANSPORT_VERSION: u16 = 7; 14 pub const RADROOTS_SIMPLEX_SMP_SENDING_PROXY_TRANSPORT_VERSION: u16 = 8; 15 pub const RADROOTS_SIMPLEX_SMP_SENDER_AUTH_KEY_TRANSPORT_VERSION: u16 = 9; 16 pub const RADROOTS_SIMPLEX_SMP_DELETED_EVENT_TRANSPORT_VERSION: u16 = 10; 17 pub const RADROOTS_SIMPLEX_SMP_ENCRYPTED_BLOCK_TRANSPORT_VERSION: u16 = 11; 18 pub const RADROOTS_SIMPLEX_SMP_BLOCKED_ENTITY_TRANSPORT_VERSION: u16 = 12; 19 pub const RADROOTS_SIMPLEX_SMP_PROXY_SERVER_HANDSHAKE_TRANSPORT_VERSION: u16 = 14; 20 pub const RADROOTS_SIMPLEX_SMP_SHORT_LINKS_TRANSPORT_VERSION: u16 = 15; 21 pub const RADROOTS_SIMPLEX_SMP_SERVICE_CERTS_TRANSPORT_VERSION: u16 = 16; 22 pub const RADROOTS_SIMPLEX_SMP_NEW_NOTIFIER_CREDENTIALS_TRANSPORT_VERSION: u16 = 17; 23 pub const RADROOTS_SIMPLEX_SMP_CURRENT_TRANSPORT_VERSION: u16 = 24 RADROOTS_SIMPLEX_SMP_NEW_NOTIFIER_CREDENTIALS_TRANSPORT_VERSION; 25 26 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 27 pub struct RadrootsSimplexSmpVersionRange { 28 pub min: u16, 29 pub max: u16, 30 } 31 32 impl RadrootsSimplexSmpVersionRange { 33 pub const fn single(version: u16) -> Self { 34 Self { 35 min: version, 36 max: version, 37 } 38 } 39 40 pub fn new(min: u16, max: u16) -> Result<Self, RadrootsSimplexSmpProtoError> { 41 if min == 0 || max == 0 || min > max { 42 return Err(RadrootsSimplexSmpProtoError::InvalidVersionRange( 43 alloc::format!("{min}-{max}"), 44 )); 45 } 46 47 Ok(Self { min, max }) 48 } 49 50 pub const fn contains(&self, version: u16) -> bool { 51 version >= self.min && version <= self.max 52 } 53 } 54 55 impl Default for RadrootsSimplexSmpVersionRange { 56 fn default() -> Self { 57 Self::single(RADROOTS_SIMPLEX_SMP_CURRENT_CLIENT_VERSION) 58 } 59 } 60 61 impl fmt::Display for RadrootsSimplexSmpVersionRange { 62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 63 if self.min == self.max { 64 write!(f, "{}", self.min) 65 } else { 66 write!(f, "{}-{}", self.min, self.max) 67 } 68 } 69 } 70 71 impl FromStr for RadrootsSimplexSmpVersionRange { 72 type Err = RadrootsSimplexSmpProtoError; 73 74 fn from_str(value: &str) -> Result<Self, Self::Err> { 75 let trimmed = value.trim(); 76 if trimmed.is_empty() { 77 return Err(RadrootsSimplexSmpProtoError::InvalidVersionRange( 78 String::new(), 79 )); 80 } 81 82 if let Some((min, max)) = trimmed.split_once('-') { 83 let min = parse_version(min, trimmed)?; 84 let max = parse_version(max, trimmed)?; 85 Self::new(min, max) 86 } else { 87 let version = parse_version(trimmed, trimmed)?; 88 Self::new(version, version) 89 } 90 } 91 } 92 93 fn parse_version(value: &str, original: &str) -> Result<u16, RadrootsSimplexSmpProtoError> { 94 value 95 .parse::<u16>() 96 .map_err(|_| RadrootsSimplexSmpProtoError::InvalidVersionRange(original.to_string())) 97 } 98 99 #[cfg(test)] 100 mod tests { 101 use super::*; 102 103 #[test] 104 fn parses_single_version_range() { 105 let range = "9".parse::<RadrootsSimplexSmpVersionRange>().unwrap(); 106 assert_eq!(range, RadrootsSimplexSmpVersionRange::single(9)); 107 assert_eq!(range.to_string(), "9"); 108 } 109 110 #[test] 111 fn parses_bounded_version_range() { 112 let range = "6-9".parse::<RadrootsSimplexSmpVersionRange>().unwrap(); 113 assert_eq!(range.min, 6); 114 assert_eq!(range.max, 9); 115 assert!(range.contains(7)); 116 assert_eq!(range.to_string(), "6-9"); 117 } 118 }