1 use super::alert::*; 2 use super::application_data::*; 3 use super::change_cipher_spec::*; 4 use super::handshake::*; 5 use crate::error::*; 6 7 use std::io::{Read, Write}; 8 9 // https://tools.ietf.org/html/rfc4346#section-6.2.1 10 #[derive(Default, Copy, Clone, PartialEq, Eq, Debug)] 11 pub enum ContentType { 12 ChangeCipherSpec = 20, 13 Alert = 21, 14 Handshake = 22, 15 ApplicationData = 23, 16 #[default] 17 Invalid, 18 } 19 20 impl From<u8> for ContentType { from(val: u8) -> Self21 fn from(val: u8) -> Self { 22 match val { 23 20 => ContentType::ChangeCipherSpec, 24 21 => ContentType::Alert, 25 22 => ContentType::Handshake, 26 23 => ContentType::ApplicationData, 27 _ => ContentType::Invalid, 28 } 29 } 30 } 31 32 #[derive(PartialEq, Debug, Clone)] 33 pub enum Content { 34 ChangeCipherSpec(ChangeCipherSpec), 35 Alert(Alert), 36 Handshake(Handshake), 37 ApplicationData(ApplicationData), 38 } 39 40 impl Content { content_type(&self) -> ContentType41 pub fn content_type(&self) -> ContentType { 42 match self { 43 Content::ChangeCipherSpec(c) => c.content_type(), 44 Content::Alert(c) => c.content_type(), 45 Content::Handshake(c) => c.content_type(), 46 Content::ApplicationData(c) => c.content_type(), 47 } 48 } 49 size(&self) -> usize50 pub fn size(&self) -> usize { 51 match self { 52 Content::ChangeCipherSpec(c) => c.size(), 53 Content::Alert(c) => c.size(), 54 Content::Handshake(c) => c.size(), 55 Content::ApplicationData(c) => c.size(), 56 } 57 } 58 marshal<W: Write>(&self, writer: &mut W) -> Result<()>59 pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> { 60 match self { 61 Content::ChangeCipherSpec(c) => c.marshal(writer), 62 Content::Alert(c) => c.marshal(writer), 63 Content::Handshake(c) => c.marshal(writer), 64 Content::ApplicationData(c) => c.marshal(writer), 65 } 66 } 67 unmarshal<R: Read>(content_type: ContentType, reader: &mut R) -> Result<Self>68 pub fn unmarshal<R: Read>(content_type: ContentType, reader: &mut R) -> Result<Self> { 69 match content_type { 70 ContentType::ChangeCipherSpec => Ok(Content::ChangeCipherSpec( 71 ChangeCipherSpec::unmarshal(reader)?, 72 )), 73 ContentType::Alert => Ok(Content::Alert(Alert::unmarshal(reader)?)), 74 ContentType::Handshake => Ok(Content::Handshake(Handshake::unmarshal(reader)?)), 75 ContentType::ApplicationData => Ok(Content::ApplicationData( 76 ApplicationData::unmarshal(reader)?, 77 )), 78 _ => Err(Error::ErrInvalidContentType), 79 } 80 } 81 } 82