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