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