use std::fmt;
#[cfg(test)]
use quickcheck::{Arbitrary, Gen};
use crate::types::Bitfield;
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct KeyServerPreferences(Bitfield);
assert_send_and_sync!(KeyServerPreferences);
impl fmt::Debug for KeyServerPreferences {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut need_comma = false;
if self.no_modify() {
f.write_str("no modify")?;
need_comma = true;
}
for i in self.0.iter_set() {
match i {
KEYSERVER_PREFERENCE_NO_MODIFY => (),
i => {
if need_comma { f.write_str(", ")?; }
write!(f, "#{}", i)?;
need_comma = true;
},
}
}
if let Some(padding) = self.0.padding_bytes() {
if need_comma { f.write_str(", ")?; }
write!(f, "+padding({} bytes)", padding)?;
}
Ok(())
}
}
impl KeyServerPreferences {
pub fn new<B: AsRef<[u8]>>(bits: B) -> Self {
KeyServerPreferences(bits.as_ref().to_vec().into())
}
pub fn empty() -> Self {
Self::new(&[])
}
pub fn as_bitfield(&self) -> &Bitfield {
&self.0
}
pub fn as_bitfield_mut(&mut self) -> &mut Bitfield {
&mut self.0
}
pub fn normalized_eq(&self, other: &Self) -> bool {
self.0.normalized_eq(&other.0)
}
pub fn get(&self, bit: usize) -> bool {
self.0.get(bit)
}
pub fn set(mut self, bit: usize) -> Self {
self.0.set(bit);
self.0.canonicalize();
self
}
pub fn clear(mut self, bit: usize) -> Self {
self.0.clear(bit);
self.0.canonicalize();
self
}
pub fn no_modify(&self) -> bool {
self.get(KEYSERVER_PREFERENCE_NO_MODIFY)
}
pub fn set_no_modify(self) -> Self {
self.set(KEYSERVER_PREFERENCE_NO_MODIFY)
}
pub fn clear_no_modify(self) -> Self {
self.clear(KEYSERVER_PREFERENCE_NO_MODIFY)
}
}
const KEYSERVER_PREFERENCE_NO_MODIFY: usize = 7;
#[cfg(test)]
impl Arbitrary for KeyServerPreferences {
fn arbitrary(g: &mut Gen) -> Self {
Self::new(Vec::arbitrary(g))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn basics() -> crate::Result<()> {
let p = KeyServerPreferences::empty();
assert_eq!(p.no_modify(), false);
let p = KeyServerPreferences::new(&[]);
assert_eq!(p.no_modify(), false);
let p = KeyServerPreferences::new(&[0xff]);
assert_eq!(p.no_modify(), true);
Ok(())
}
quickcheck! {
fn roundtrip(val: KeyServerPreferences) -> bool {
let mut q_bytes = val.as_bitfield().as_bytes().to_vec();
let q = KeyServerPreferences::new(&q_bytes);
assert_eq!(val, q);
assert!(val.normalized_eq(&q));
q_bytes.push(0);
let q = KeyServerPreferences::new(&q_bytes);
assert!(val != q);
assert!(val.normalized_eq(&q));
q_bytes.push(0);
let q = KeyServerPreferences::new(&q_bytes);
assert!(val != q);
assert!(val.normalized_eq(&q));
true
}
}
}