use alloc::vec;
use alloc::vec::Vec;
use mls_rs_codec::{MlsDecode, MlsEncode, MlsSize};
use crate::{
crypto::CipherSuite,
extension::{ExtensionList, ExtensionType},
identity::{CredentialType, SigningIdentity},
protocol_version::ProtocolVersion,
};
use super::ProposalType;
#[derive(Clone, PartialEq, Eq, Debug, MlsSize, MlsEncode, MlsDecode)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[cfg_attr(
all(feature = "ffi", not(test)),
safer_ffi_gen::ffi_type(clone, opaque)
)]
pub struct Capabilities {
pub protocol_versions: Vec<ProtocolVersion>,
pub cipher_suites: Vec<CipherSuite>,
pub extensions: Vec<ExtensionType>,
pub proposals: Vec<ProposalType>,
pub credentials: Vec<CredentialType>,
}
#[cfg_attr(all(feature = "ffi", not(test)), safer_ffi_gen::safer_ffi_gen)]
impl Capabilities {
#[cfg(feature = "ffi")]
pub fn protocol_versions(&self) -> &[ProtocolVersion] {
&self.protocol_versions
}
#[cfg(feature = "ffi")]
pub fn cipher_suites(&self) -> &[CipherSuite] {
&self.cipher_suites
}
#[cfg(feature = "ffi")]
pub fn extensions(&self) -> &[ExtensionType] {
&self.extensions
}
#[cfg(feature = "ffi")]
pub fn proposals(&self) -> &[ProposalType] {
&self.proposals
}
#[cfg(feature = "ffi")]
pub fn credentials(&self) -> &[CredentialType] {
&self.credentials
}
}
impl Default for Capabilities {
fn default() -> Self {
use crate::identity::BasicCredential;
Self {
protocol_versions: vec![ProtocolVersion::MLS_10],
cipher_suites: CipherSuite::all().collect(),
extensions: Default::default(),
proposals: Default::default(),
credentials: vec![BasicCredential::credential_type()],
}
}
}
#[cfg_attr(
all(feature = "ffi", not(test)),
safer_ffi_gen::ffi_type(clone, opaque)
)]
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct Member {
pub index: u32,
pub signing_identity: SigningIdentity,
pub capabilities: Capabilities,
pub extensions: ExtensionList,
}
#[cfg_attr(all(feature = "ffi", not(test)), safer_ffi_gen::safer_ffi_gen)]
impl Member {
pub fn new(
index: u32,
signing_identity: SigningIdentity,
capabilities: Capabilities,
extensions: ExtensionList,
) -> Self {
Self {
index,
signing_identity,
capabilities,
extensions,
}
}
#[cfg(feature = "ffi")]
pub fn index(&self) -> u32 {
self.index
}
#[cfg(feature = "ffi")]
pub fn signing_identity(&self) -> &SigningIdentity {
&self.signing_identity
}
#[cfg(feature = "ffi")]
pub fn capabilities(&self) -> &Capabilities {
&self.capabilities
}
#[cfg(feature = "ffi")]
pub fn extensions(&self) -> &ExtensionList {
&self.extensions
}
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
#[cfg_attr(
all(feature = "ffi", not(test)),
safer_ffi_gen::ffi_type(clone, opaque)
)]
pub struct MemberUpdate {
pub prior: Member,
pub new: Member,
}
#[cfg_attr(all(feature = "ffi", not(test)), safer_ffi_gen::safer_ffi_gen)]
impl MemberUpdate {
pub fn new(prior: Member, new: Member) -> MemberUpdate {
MemberUpdate { prior, new }
}
pub fn index(&self) -> u32 {
self.new.index
}
#[cfg(feature = "ffi")]
pub fn before_update(&self) -> &Member {
&self.prior
}
#[cfg(feature = "ffi")]
pub fn after_update(&self) -> &Member {
&self.new
}
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct RosterUpdate {
pub(crate) added: Vec<Member>,
pub(crate) removed: Vec<Member>,
pub(crate) updated: Vec<MemberUpdate>,
}
impl RosterUpdate {
pub fn new(
mut added: Vec<Member>,
mut removed: Vec<Member>,
mut updated: Vec<MemberUpdate>,
) -> RosterUpdate {
added.sort_by_key(|m| m.index);
removed.sort_by_key(|m| m.index);
updated.sort_by_key(|u| u.index());
RosterUpdate {
added,
removed,
updated,
}
}
pub fn added(&self) -> &[Member] {
&self.added
}
pub fn removed(&self) -> &[Member] {
&self.removed
}
pub fn updated(&self) -> &[MemberUpdate] {
&self.updated
}
}