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