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