1use std::io::{Read, Write};
2
3use super::alert::*;
4use super::application_data::*;
5use super::change_cipher_spec::*;
6use super::handshake::*;
7use shared::error::*;
8
9#[derive(Default, Copy, Clone, PartialEq, Eq, Debug)]
15pub enum ContentType {
16 ChangeCipherSpec = 20,
18 Alert = 21,
20 Handshake = 22,
22 ApplicationData = 23,
24 #[default]
25 Invalid,
27}
28
29impl From<u8> for ContentType {
30 fn from(val: u8) -> Self {
31 match val {
32 20 => ContentType::ChangeCipherSpec,
33 21 => ContentType::Alert,
34 22 => ContentType::Handshake,
35 23 => ContentType::ApplicationData,
36 _ => ContentType::Invalid,
37 }
38 }
39}
40
41#[derive(PartialEq, Debug, Clone)]
42pub enum Content {
44 ChangeCipherSpec(ChangeCipherSpec),
46 Alert(Alert),
48 Handshake(Handshake),
50 ApplicationData(ApplicationData),
52}
53
54impl Content {
55 pub fn content_type(&self) -> ContentType {
57 match self {
58 Content::ChangeCipherSpec(c) => c.content_type(),
59 Content::Alert(c) => c.content_type(),
60 Content::Handshake(c) => c.content_type(),
61 Content::ApplicationData(c) => c.content_type(),
62 }
63 }
64
65 pub fn size(&self) -> usize {
67 match self {
68 Content::ChangeCipherSpec(c) => c.size(),
69 Content::Alert(c) => c.size(),
70 Content::Handshake(c) => c.size(),
71 Content::ApplicationData(c) => c.size(),
72 }
73 }
74
75 pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
81 match self {
82 Content::ChangeCipherSpec(c) => c.marshal(writer),
83 Content::Alert(c) => c.marshal(writer),
84 Content::Handshake(c) => c.marshal(writer),
85 Content::ApplicationData(c) => c.marshal(writer),
86 }
87 }
88
89 pub fn unmarshal<R: Read>(content_type: ContentType, reader: &mut R) -> Result<Self> {
95 match content_type {
96 ContentType::ChangeCipherSpec => Ok(Content::ChangeCipherSpec(
97 ChangeCipherSpec::unmarshal(reader)?,
98 )),
99 ContentType::Alert => Ok(Content::Alert(Alert::unmarshal(reader)?)),
100 ContentType::Handshake => Ok(Content::Handshake(Handshake::unmarshal(reader)?)),
101 ContentType::ApplicationData => Ok(Content::ApplicationData(
102 ApplicationData::unmarshal(reader)?,
103 )),
104 _ => Err(Error::ErrInvalidContentType),
105 }
106 }
107}