sheave_core/messages/
fc_publish.rs

1use std::io::Result as IOResult;
2use super::{
3    Channel,
4    ChunkData,
5    Command,
6    headers::MessageType
7};
8use crate::{
9    Decoder,
10    Encoder,
11    ByteBuffer,
12    messages::amf::v0::{
13        AmfString,
14        Null
15    }
16};
17
18/// The command to tell a path to the server.
19///
20/// Typically, this becomes same as the releaseStream's one.
21/// Following format is required:
22///
23/// |Field|AMF Type|Value|
24/// | :- | :- | :- |
25/// ||[`Null`]|Nothing but an AMF's type marker is in.|
26/// |Path|[`String`]|Same as the releaseStream request.|
27///
28/// [`Null`]: crate::messages::amf::v0::Null
29/// [`String`]: crate::messages::amf::v0::AmfString
30#[derive(Debug, Clone, PartialEq)]
31pub struct FcPublish(AmfString);
32
33impl FcPublish {
34    /// Constructs a FcPublish command.
35    pub fn new(topic_path: AmfString) -> Self {
36        Self(topic_path)
37    }
38
39    /// Gets the topic path.
40    pub fn get_topic_path(&self) -> &AmfString {
41        &self.0
42    }
43}
44
45impl From<FcPublish> for AmfString {
46    fn from(fc_publish: FcPublish) -> Self {
47        fc_publish.0
48    }
49}
50
51impl ChunkData for FcPublish {
52    const CHANNEL: Channel = Channel::System;
53    const MESSAGE_TYPE: MessageType = MessageType::Command;
54}
55
56impl Command for FcPublish {}
57
58impl Decoder<FcPublish> for ByteBuffer {
59    /// Decodes bytes into a FcPublish command.
60    ///
61    /// # Errors
62    ///
63    /// * [`InsufficientBufferLength`]
64    ///
65    /// When some field misses.
66    ///
67    /// * [`InconsistentMarker`]
68    ///
69    /// When some value is inconsistent with its marker.
70    ///
71    /// * [`InvalidString`]
72    ///
73    /// When some value is invalid for UTF-8 string.
74    ///
75    /// # Examples
76    ///
77    /// ```rust
78    /// use sheave_core::{
79    ///     ByteBuffer,
80    ///     Decoder,
81    ///     Encoder,
82    ///     messages::{
83    ///         FcPublish,
84    ///         amf::v0::{
85    ///             AmfString,
86    ///             Null
87    ///         }
88    ///     }
89    /// };
90    ///
91    /// let mut buffer = ByteBuffer::default();
92    /// buffer.encode(&Null);
93    /// buffer.encode(&AmfString::default());
94    /// assert!(Decoder::<FcPublish>::decode(&mut buffer).is_ok());
95    ///
96    /// let mut buffer = ByteBuffer::default();
97    /// assert!(Decoder::<FcPublish>::decode(&mut buffer).is_err())
98    /// ```
99    ///
100    /// [`InsufficientBufferLength`]: crate::byte_buffer::InsufficientBufferLength
101    /// [`InconsistentMarker`]: crate::messages::amf::InconsistentMarker
102    /// [`InvalidString`]: crate::messages::amf::InvalidString
103    fn decode(&mut self) -> IOResult<FcPublish> {
104        Decoder::<Null>::decode(self)?;
105        let topic_path: AmfString = self.decode()?;
106        Ok(FcPublish(topic_path))
107    }
108}
109
110impl Encoder<FcPublish> for ByteBuffer {
111    /// Encodes a FcPublish command into bytes.
112    fn encode(&mut self, fc_publish: &FcPublish) {
113        self.encode(&Null);
114        self.encode(fc_publish.get_topic_path());
115    }
116}
117
118#[cfg(test)]
119mod tests {
120    use super::*;
121
122    #[test]
123    fn decode_fc_publish() {
124        let mut buffer = ByteBuffer::default();
125        buffer.encode(&Null);
126        buffer.encode(&AmfString::default());
127        let result: IOResult<FcPublish> = buffer.decode();
128        assert!(result.is_ok());
129        let actual = result.unwrap();
130        let expected = FcPublish::new(AmfString::default());
131        assert_eq!(expected, actual)
132    }
133
134    #[test]
135    fn encode_fc_publish() {
136        let mut buffer = ByteBuffer::default();
137        let expected_topic_path = "";
138        let expected = FcPublish::new(AmfString::from(expected_topic_path));
139        buffer.encode(&expected);
140        Decoder::<Null>::decode(&mut buffer).unwrap();
141        let actual_topic_path: AmfString = buffer.decode().unwrap();
142        assert_eq!(expected_topic_path, actual_topic_path)
143    }
144}