Files
empidee/src/commands/client_to_client/channels.rs
T
oysteikt 56d7c942db commands: remove toplevel Request/Response enums
This also exposes all the command types as public API
2026-06-21 15:39:23 +09:00

75 lines
1.9 KiB
Rust

use serde::{Deserialize, Serialize};
use crate::{
commands::{Command, CommandResponse, ResponseParserError, empty_command_request},
response_tokenizer::{ResponseAttributes, expect_property_type},
types::ChannelName,
};
pub struct Channels;
empty_command_request!(Channels, "channels");
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ChannelsResponse {
pub channels: Vec<ChannelName>,
}
impl ChannelsResponse {
pub fn new(channels: Vec<ChannelName>) -> Self {
ChannelsResponse { channels }
}
}
impl CommandResponse for ChannelsResponse {
fn parse(parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError> {
let parts: Vec<_> = parts.into_vec()?;
let mut channel_names = Vec::with_capacity(parts.len());
for (key, value) in parts {
debug_assert!(key == "channels");
let channel_name = expect_property_type!(Some(value), "channels", Text);
let channel_name = channel_name
.parse()
.map_err(|_| ResponseParserError::SyntaxError(0, channel_name.to_string()))?;
channel_names.push(channel_name);
}
Ok(ChannelsResponse {
channels: channel_names,
})
}
}
impl Command for Channels {
type Request = ChannelsRequest;
type Response = ChannelsResponse;
}
#[cfg(test)]
mod tests {
use super::*;
use indoc::indoc;
#[test]
fn test_parse_response() {
let response = indoc! {"
channels: foo
channels: bar
channels: baz
OK
"};
let response = Channels::parse_raw_response(response.as_bytes()).unwrap();
assert_eq!(
response,
ChannelsResponse {
channels: vec![
"foo".parse().unwrap(),
"bar".parse().unwrap(),
"baz".parse().unwrap(),
]
}
);
}
}