#![cfg_attr(not(feature = "std"), no_std)]
#![deny(missing_docs)]
extern crate ascii;
#[macro_use]
mod impl_macro;
#[cfg(feature = "std")]
use ascii::AsAsciiStr;
use ascii::AsciiStr;
#[cfg(feature = "std")]
use std::fmt::{Display, Formatter, Result};
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub struct Callpass(u16);
impl Callpass {
fn new(callsign: &AsciiStr) -> Callpass {
Callpass({
let (hash, _) = callsign
.into_iter()
.map(|char| {
let mut d = *char;
d.make_ascii_uppercase();
d.as_byte() as u16
})
.fold((0x73e2, true), |(hash, switch), input| {
let hash = match switch {
true => hash ^ input << 8,
false => hash ^ input,
};
(hash, !switch)
});
hash & 0x7fff
})
}
}
generate_impl_from_numeric!(u16, i16, u32, i32, u64, i64);
generate_impl_partialeq!(u16, i16, u32, i32, u64, i64);
#[cfg(feature = "std")]
impl Display for Callpass {
fn fmt(&self, f: &mut Formatter) -> Result {
write!(f, "{:05}", self.0)
}
}
#[cfg(feature = "std")]
impl From<Callpass> for String {
fn from(callpass: Callpass) -> String {
format!("{:05}", callpass)
}
}
#[cfg(feature = "std")]
impl From<String> for Callpass {
fn from(callsign: String) -> Self {
match callsign.as_ascii_str() {
Ok(ascii_call) => Callpass::new(ascii_call),
Err(err) => panic!("{}", &err),
}
}
}
#[cfg(feature = "std")]
impl<'a> From<&'a String> for Callpass {
fn from(callsign: &'a String) -> Self {
match callsign.as_ascii_str() {
Ok(ascii_call) => Callpass::new(ascii_call),
Err(err) => panic!("{}", &err),
}
}
}
impl<'a> From<&'a str> for Callpass {
fn from(callsign: &'a str) -> Self {
match AsciiStr::from_ascii(callsign) {
Ok(ascii_str) => Callpass::new(ascii_str),
Err(err) => panic!("{}", &err),
}
}
}