scuffle_rtmp/command_messages/
reader.rs1use std::convert::Infallible;
4use std::str::FromStr;
5
6use bytes::Bytes;
7use scuffle_amf0::decoder::Amf0Decoder;
8use scuffle_bytes_util::StringCow;
9use scuffle_bytes_util::zero_copy::BytesBuf;
10
11use super::error::CommandError;
12use super::netconnection::NetConnectionCommand;
13use super::netstream::NetStreamCommand;
14use super::{Command, CommandResultLevel, CommandType, UnknownCommand};
15
16impl Command<'_> {
17 pub fn read(payload: Bytes) -> Result<Self, CommandError> {
19 let mut decoder = Amf0Decoder::from_buf(payload);
20
21 let command_name = decoder.decode_string()?;
22 let transaction_id = decoder.decode_number()?;
23
24 let command_type = CommandType::read(command_name, &mut decoder)?;
25
26 Ok(Self {
27 transaction_id,
28 command_type,
29 })
30 }
31}
32
33impl<'a> CommandType<'a> {
34 fn read(command_name: StringCow<'a>, decoder: &mut Amf0Decoder<BytesBuf<Bytes>>) -> Result<Self, CommandError> {
35 if let Some(command) = NetConnectionCommand::read(command_name.as_str(), decoder)? {
36 return Ok(Self::NetConnection(command));
37 }
38
39 if let Some(command) = NetStreamCommand::read(command_name.as_str(), decoder)? {
40 return Ok(Self::NetStream(command));
41 }
42
43 let values = decoder.decode_all()?;
44 Ok(Self::Unknown(UnknownCommand { command_name, values }))
45 }
46}
47
48impl FromStr for CommandResultLevel {
49 type Err = Infallible;
50
51 fn from_str(s: &str) -> Result<Self, Self::Err> {
52 match s {
53 "warning" => Ok(Self::Warning),
54 "status" => Ok(Self::Status),
55 "error" => Ok(Self::Error),
56 _ => Ok(Self::Unknown(s.to_string())),
57 }
58 }
59}
60
61#[cfg(test)]
62#[cfg_attr(all(test, coverage_nightly), coverage(off))]
63mod tests {
64 use super::CommandResultLevel;
65
66 #[test]
67 fn test_command_result_level() {
68 assert_eq!("warning".parse::<CommandResultLevel>().unwrap(), CommandResultLevel::Warning);
69 assert_eq!("status".parse::<CommandResultLevel>().unwrap(), CommandResultLevel::Status);
70 assert_eq!("error".parse::<CommandResultLevel>().unwrap(), CommandResultLevel::Error);
71 assert_eq!(
72 "unknown".parse::<CommandResultLevel>().unwrap(),
73 CommandResultLevel::Unknown("unknown".to_string())
74 );
75 }
76}