bloop-protocol 1.1.0

Core implementation of the Bloop wire protocol
//! Server capability flags.

use bitmask_enum::bitmask;

use crate::codec::{Decode, DecodeError, Encode, EncodeError};

/// Bitmask of capabilities supported by the server.
///
/// Exchanged in the server handshake as a little-endian `u64`. Unknown bits
/// may be defined by future minor protocol versions; clients must ignore
/// them, and encode/decode preserves them.
#[bitmask(u64)]
#[bitmask_config(vec_debug)]
pub enum Capabilities {
    /// The server supports the preload check message pair.
    PreloadCheck = 0x1,
}

impl Encode for Capabilities {
    fn encode(&self, out: &mut Vec<u8>) -> Result<(), EncodeError> {
        self.bits().encode(out)
    }
}

impl Decode for Capabilities {
    fn decode(input: &mut &[u8]) -> Result<Self, DecodeError> {
        Ok(Self::from(u64::decode(input)?))
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::codec::{decode_payload, encode_payload};

    #[test]
    fn capabilities_encode_as_little_endian_u64() {
        let encoded = encode_payload(&Capabilities::PreloadCheck).unwrap();
        assert_eq!(encoded, [1, 0, 0, 0, 0, 0, 0, 0]);

        let decoded = decode_payload::<Capabilities>(&encoded).unwrap();
        assert!(decoded.contains(Capabilities::PreloadCheck));
    }

    #[test]
    fn unknown_bits_are_preserved() {
        let payload = [0xff; 8];
        let decoded = decode_payload::<Capabilities>(&payload).unwrap();

        assert!(decoded.contains(Capabilities::PreloadCheck));
        assert_eq!(encode_payload(&decoded).unwrap(), payload);
    }
}