1 use super::prelude::*;
2 
3 #[derive(Debug)]
4 pub struct qSupported<'a> {
5     pub features: Features<'a>,
6 }
7 
8 impl<'a> ParseCommand<'a> for qSupported<'a> {
from_packet(buf: PacketBuf<'a>) -> Option<Self>9     fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {
10         let body = buf.into_body();
11         if body.is_empty() {
12             return None;
13         }
14 
15         Some(qSupported {
16             features: Features(body),
17         })
18     }
19 }
20 
21 #[derive(Debug)]
22 pub struct Features<'a>(&'a [u8]);
23 
24 impl<'a> Features<'a> {
into_iter(self) -> impl Iterator<Item = Option<Feature<'a>>> + 'a25     pub fn into_iter(self) -> impl Iterator<Item = Option<Feature<'a>>> + 'a {
26         self.0.split(|b| *b == b';').map(|s| match s.last() {
27             None => None,
28             Some(&c) if c == b'+' || c == b'-' || c == b'?' => Some(Feature {
29                 name: s[..s.len() - 1].into(),
30                 val: None,
31                 status: match c {
32                     b'+' => FeatureSupported::Yes,
33                     b'-' => FeatureSupported::No,
34                     b'?' => FeatureSupported::Maybe,
35                     _ => return None,
36                 },
37             }),
38             Some(_) => {
39                 let mut parts = s.split(|b| *b == b'=');
40                 Some(Feature {
41                     name: parts.next()?.into(),
42                     val: Some(parts.next()?.into()),
43                     status: FeatureSupported::Yes,
44                 })
45             }
46         })
47     }
48 }
49 
50 #[derive(Debug)]
51 pub enum FeatureSupported {
52     Yes,
53     No,
54     Maybe,
55 }
56 
57 #[derive(Debug)]
58 pub struct Feature<'a> {
59     name: Bstr<'a>,
60     val: Option<Bstr<'a>>,
61     status: FeatureSupported,
62 }
63