Skip to main content

mls_spec/messages/
content_type.rs

1use crate::{
2    MlsSpecError,
3    group::{commits::Commit, proposals::Proposal},
4};
5
6#[derive(
7    Debug,
8    Clone,
9    Copy,
10    PartialEq,
11    Eq,
12    tls_codec::TlsSerialize,
13    tls_codec::TlsDeserialize,
14    tls_codec::TlsSize,
15    strum::Display,
16)]
17#[strum(prefix = "ContentType")]
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19#[repr(u8)]
20#[non_exhaustive]
21pub enum ContentType {
22    Reserved = 0x00,
23    Application = 0x01,
24    Proposal = 0x02,
25    Commit = 0x03,
26    #[cfg(feature = "draft-mahy-mls-new-content-types")]
27    Status = crate::drafts::new_content_types::CONTENT_TYPE_STATUS,
28    #[cfg(feature = "draft-mahy-mls-new-content-types")]
29    Ephemeral = crate::drafts::new_content_types::CONTENT_TYPE_EPHEMERAL,
30    #[cfg(feature = "draft-mularczyk-mls-splitcommit")]
31    SplitCommit = crate::drafts::split_commit::CONTENT_TYPE_SPLIT_COMMIT,
32}
33
34impl TryFrom<u8> for ContentType {
35    type Error = MlsSpecError;
36
37    fn try_from(value: u8) -> Result<Self, Self::Error> {
38        let ct = match value {
39            0x00 => Self::Reserved,
40            0x01 => Self::Application,
41            0x02 => Self::Proposal,
42            0x03 => Self::Commit,
43            #[cfg(feature = "draft-mahy-mls-new-content-types")]
44            crate::drafts::new_content_types::CONTENT_TYPE_STATUS => Self::Status,
45            #[cfg(feature = "draft-mahy-mls-new-content-types")]
46            crate::drafts::new_content_types::CONTENT_TYPE_EPHEMERAL => Self::Ephemeral,
47            #[cfg(feature = "draft-mularczyk-mls-splitcommit")]
48            crate::drafts::split_commit::CONTENT_TYPE_SPLIT_COMMIT => Self::SplitCommit,
49            _ => return Err(MlsSpecError::InvalidContentType),
50        };
51
52        Ok(ct)
53    }
54}
55
56#[derive(
57    Debug,
58    Clone,
59    PartialEq,
60    Eq,
61    tls_codec::TlsSerialize,
62    tls_codec::TlsDeserialize,
63    tls_codec::TlsSize,
64)]
65#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
66#[repr(u8)]
67pub enum ContentTypeInner {
68    #[tls_codec(discriminant = "ContentType::Application")]
69    Application {
70        #[tls_codec(with = "crate::tlspl::bytes")]
71        application_data: Vec<u8>,
72    },
73    #[tls_codec(discriminant = "ContentType::Proposal")]
74    Proposal { proposal: Proposal },
75    #[tls_codec(discriminant = "ContentType::Commit")]
76    Commit { commit: Commit },
77    #[cfg(feature = "draft-mularczyk-mls-splitcommit")]
78    #[tls_codec(discriminant = "ContentType::SplitCommit")]
79    SplitCommit {
80        split_commit: crate::drafts::split_commit::SplitCommit,
81    },
82    #[cfg(feature = "draft-mahy-mls-new-content-types")]
83    #[tls_codec(discriminant = "ContentType::Status")]
84    Status {
85        #[tls_codec(with = "crate::tlspl::bytes")]
86        application_data: Vec<u8>,
87    },
88    #[cfg(feature = "draft-mahy-mls-new-content-types")]
89    #[tls_codec(discriminant = "ContentType::Ephemeral")]
90    Ephemeral {
91        #[tls_codec(with = "crate::tlspl::bytes")]
92        application_data: Vec<u8>,
93    },
94}
95
96impl From<&ContentTypeInner> for ContentType {
97    fn from(value: &ContentTypeInner) -> Self {
98        match value {
99            ContentTypeInner::Application { .. } => ContentType::Application,
100            ContentTypeInner::Proposal { .. } => ContentType::Proposal,
101            ContentTypeInner::Commit { .. } => ContentType::Commit,
102            #[cfg(feature = "draft-mularczyk-mls-splitcommit")]
103            ContentTypeInner::SplitCommit { .. } => ContentType::SplitCommit,
104            #[cfg(feature = "draft-mahy-mls-new-content-types")]
105            ContentTypeInner::Status { .. } => ContentType::Status,
106            #[cfg(feature = "draft-mahy-mls-new-content-types")]
107            ContentTypeInner::Ephemeral { .. } => ContentType::Ephemeral,
108        }
109    }
110}