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