use std::fmt;
use Fingerprint;
use KeyID;
use Result;
impl fmt::Display for Fingerprint {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.to_string())
}
}
impl fmt::Debug for Fingerprint {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("Fingerprint")
.field(&self.to_string())
.finish()
}
}
impl Fingerprint {
pub fn from_bytes(raw: &[u8]) -> Fingerprint {
if raw.len() == 20 {
let mut fp : [u8; 20] = Default::default();
fp.copy_from_slice(raw);
Fingerprint::V4(fp)
} else {
Fingerprint::Invalid(raw.to_vec().into_boxed_slice())
}
}
pub fn from_hex(hex: &str) -> Result<Fingerprint> {
Ok(Fingerprint::from_bytes(&::conversions::from_hex(hex, true)?[..]))
}
pub fn as_slice(&self) -> &[u8] {
match self {
&Fingerprint::V4(ref fp) => fp,
&Fingerprint::Invalid(ref fp) => fp,
}
}
pub fn to_string(&self) -> String {
self.convert_to_string(true)
}
pub fn to_hex(&self) -> String {
self.convert_to_string(false)
}
fn convert_to_string(&self, pretty: bool) -> String {
let raw = match self {
&Fingerprint::V4(ref fp) => &fp[..],
&Fingerprint::Invalid(ref fp) => &fp[..],
};
let mut output = Vec::with_capacity(
raw.len() * 2
+ if pretty {
raw.len() / 2
+ raw.len() / 10
} else { 0 });
for (i, b) in raw.iter().enumerate() {
if pretty && i > 0 && i % 2 == 0 {
output.push(' ' as u8);
}
if pretty && i > 0 && i % 10 == 0 {
output.push(' ' as u8);
}
let top = b >> 4;
let bottom = b & 0xFu8;
if top < 10u8 {
output.push('0' as u8 + top)
} else {
output.push('A' as u8 + (top - 10u8))
}
if bottom < 10u8 {
output.push('0' as u8 + bottom)
} else {
output.push('A' as u8 + (bottom - 10u8))
}
}
String::from_utf8(output).unwrap()
}
pub fn to_keyid(&self) -> KeyID {
match self {
&Fingerprint::V4(ref fp) =>
KeyID::from_bytes(&fp[fp.len() - 8..]),
&Fingerprint::Invalid(ref fp) => {
if fp.len() < 8 {
KeyID::from_bytes(&[0; 8])
} else {
KeyID::from_bytes(&fp[fp.len() - 8..])
}
}
}
}
pub fn to_icao(&self) -> String {
let mut ret = String::default();
for ch in self.to_hex().chars() {
let word = match ch {
'0' => "Zero",
'1' => "One",
'2' => "Two",
'3' => "Three",
'4' => "Four",
'5' => "Five",
'6' => "Six",
'7' => "Seven",
'8' => "Eight",
'9' => "Niner",
'A' => "Alpha",
'B' => "Bravo",
'C' => "Charlie",
'D' => "Delta",
'E' => "Echo",
'F' => "Foxtrot",
_ => { continue; }
};
if !ret.is_empty() {
ret.push_str(" ");
}
ret.push_str(word);
}
ret
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn icao() {
let fpr = Fingerprint::from_hex(
"0123 4567 89AB CDEF 0123 4567 89AB CDEF 0123 4567").unwrap();
let expected = "\
Zero One Two Three Four Five Six Seven Eight Niner Alpha Bravo Charlie Delta \
Echo Foxtrot Zero One Two Three Four Five Six Seven Eight Niner Alpha Bravo \
Charlie Delta Echo Foxtrot Zero One Two Three Four Five Six Seven";
assert_eq!(fpr.to_icao(), expected);
}
}