Skip to main content

coven_format/
invite_end.rs

1//! The marker an ended invite leaves at its join request's path (D9, D10).
2
3use crate::error::{exact_length, Error};
4
5/// What an ended invite leaves at `<store>/join-requests/<device>/<invite>`, created
6/// once in place of the request: a joining device that finds it there ends
7/// its join as declined, and a request sent after the invite ended finds the
8/// path taken. It holds no secret, only the time after which any device may
9/// delete it.
10#[derive(Clone, Copy, Debug, PartialEq, Eq)]
11pub struct InviteEnd {
12    /// Seconds since the Unix epoch after which the marker may go: a
13    /// joining device sends no first request by then.
14    pub kept_until: u64,
15}
16
17const KIND: u8 = crate::kinds::ENDED_INVITE;
18const LENGTH: usize = 3 + 8;
19
20impl InviteEnd {
21    /// The marker's complete bytes: its kind, format and time.
22    pub fn encode(&self) -> Vec<u8> {
23        let mut bytes = Vec::with_capacity(LENGTH);
24        bytes.extend_from_slice(&crate::FormatVersion::CURRENT.prefix(KIND));
25        bytes.extend_from_slice(&self.kept_until.to_be_bytes());
26        bytes
27    }
28
29    /// Read a marker. Bytes of another kind, such as a join request, fail
30    /// with `UnknownTag`.
31    pub fn decode(bytes: &[u8]) -> Result<Self, Error> {
32        crate::sealed::prefix(bytes, KIND)?;
33        exact_length(bytes.len(), LENGTH)?;
34        let time: [u8; 8] = bytes[3..LENGTH].try_into().expect("eight bytes");
35        Ok(Self { kept_until: u64::from_be_bytes(time) })
36    }
37}
38
39#[cfg(test)]
40#[path = "invite_end_tests.rs"]
41mod tests;