1use std::io::{self, Write};
2
3use crate::{Error, Kind, State, parser};
4
5#[derive(Clone, Copy, Debug, Default)]
12pub struct CapabilityReply<'a> {
13 states: Option<&'a [State]>,
14 kinds: Option<&'a [Kind]>,
15}
16
17impl<'a> CapabilityReply<'a> {
18 #[must_use]
20 pub const fn new() -> Self {
21 Self {
22 states: None,
23 kinds: None,
24 }
25 }
26
27 #[must_use]
29 pub const fn states(mut self, states: &'a [State]) -> Self {
30 self.states = Some(states);
31 self
32 }
33
34 #[must_use]
36 pub const fn kinds(mut self, kinds: &'a [Kind]) -> Self {
37 self.kinds = Some(kinds);
38 self
39 }
40
41 pub fn write_to<W: Write + ?Sized>(self, output: &mut W) -> Result<(), Error> {
49 let mut frame = [0; parser::MAX_SEQUENCE];
50 let length = self
51 .encode(&mut frame)
52 .map_err(|_| parser::Error::Limit(parser::Limit::Sequence))?;
53 output.write_all(&frame[..length])?;
54 Ok(())
55 }
56
57 fn encode(self, frame: &mut [u8]) -> io::Result<usize> {
58 let capacity = frame.len();
59 let mut remaining = frame;
60 remaining.write_all(b"\x1b]7501;?")?;
61 if let Some(states) = self.states {
62 write_list(
63 &mut remaining,
64 b":states=",
65 states.iter().copied().map(State::as_str),
66 )?;
67 }
68 if let Some(kinds) = self.kinds {
69 write_list(
70 &mut remaining,
71 b":kinds=",
72 kinds.iter().copied().map(Kind::as_str),
73 )?;
74 }
75 remaining.write_all(b"\x1b\\")?;
76 Ok(capacity - remaining.len())
77 }
78}
79
80fn write_list(
81 output: &mut impl Write,
82 key: &[u8],
83 values: impl Iterator<Item = &'static str>,
84) -> io::Result<()> {
85 output.write_all(key)?;
86 for (index, value) in values.enumerate() {
87 if index != 0 {
88 output.write_all(b",")?;
89 }
90 output.write_all(value.as_bytes())?;
91 }
92 Ok(())
93}