webrtc_sctp/chunk/
chunk_error.rs1use std::fmt;
2
3use bytes::{Bytes, BytesMut};
4
5use super::chunk_header::*;
6use super::chunk_type::*;
7use super::*;
8use crate::error_cause::*;
9
10#[derive(Default, Debug, Clone)]
32pub(crate) struct ChunkError {
33 pub(crate) error_causes: Vec<ErrorCause>,
34}
35
36impl fmt::Display for ChunkError {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 let mut res = vec![self.header().to_string()];
40
41 for cause in &self.error_causes {
42 res.push(format!(" - {cause}"));
43 }
44
45 write!(f, "{}", res.join("\n"))
46 }
47}
48
49impl Chunk for ChunkError {
50 fn header(&self) -> ChunkHeader {
51 ChunkHeader {
52 typ: CT_ERROR,
53 flags: 0,
54 value_length: self.value_length() as u16,
55 }
56 }
57
58 fn unmarshal(raw: &Bytes) -> Result<Self> {
59 let header = ChunkHeader::unmarshal(raw)?;
60
61 if header.typ != CT_ERROR {
62 return Err(Error::ErrChunkTypeNotCtError);
63 }
64
65 let mut error_causes = vec![];
66 let mut offset = CHUNK_HEADER_SIZE;
67 while offset + 4 <= raw.len() {
68 let e = ErrorCause::unmarshal(
69 &raw.slice(offset..CHUNK_HEADER_SIZE + header.value_length()),
70 )?;
71 offset += e.length();
72 error_causes.push(e);
73 }
74
75 Ok(ChunkError { error_causes })
76 }
77
78 fn marshal_to(&self, buf: &mut BytesMut) -> Result<usize> {
79 self.header().marshal_to(buf)?;
80 for ec in &self.error_causes {
81 buf.extend(ec.marshal());
82 }
83 Ok(buf.len())
84 }
85
86 fn check(&self) -> Result<()> {
87 Ok(())
88 }
89
90 fn value_length(&self) -> usize {
91 self.error_causes
92 .iter()
93 .fold(0, |length, ec| length + ec.length())
94 }
95
96 fn as_any(&self) -> &(dyn Any + Send + Sync) {
97 self
98 }
99}