xref: /webrtc/dtls/src/content.rs (revision 97921129)
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