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 67 68 69 70 71 72 73
pub trait MatchCondition : Send + 'static { fn match_cond(&mut self, buf: &[u8]) -> Result<usize, usize>; } impl MatchCondition for usize { fn match_cond(&mut self, buf: &[u8]) -> Result<usize, usize> { if buf.len() >= *self { Ok(*self) } else { *self -= buf.len(); Err(buf.len()) } } } impl MatchCondition for u8 { fn match_cond(&mut self, buf: &[u8]) -> Result<usize, usize> { if let Some(len) = buf.iter().position(|&x| x == *self) { Ok(len+1) } else { Err(buf.len()) } } } impl MatchCondition for &'static [u8] { fn match_cond(&mut self, buf: &[u8]) -> Result<usize, usize> { let mut cur = 0; if !self.is_empty() { let head = self[0]; let tail = &self[1..]; let mut it = buf.iter(); while let Some(mut len) = it.position(|&x| x == head) { len += cur + 1; let buf = &buf[len..]; if buf.len() < tail.len() { return Err(len - 1); } else if buf.starts_with(tail) { return Ok(len + tail.len()); } cur = len; it = buf.iter(); } cur = buf.len(); } Err(cur) } } impl MatchCondition for char { fn match_cond(&mut self, buf: &[u8]) -> Result<usize, usize> { (*self as u8).match_cond(buf) } } impl MatchCondition for &'static str { fn match_cond(&mut self, buf: &[u8]) -> Result<usize, usize> { self.as_bytes().match_cond(buf) } } #[test] fn test_match_cond() { assert!((5 as usize).match_cond("hello".as_bytes()) == Ok(5)); assert!((5 as usize).match_cond("hello world".as_bytes()) == Ok(5)); assert!((10 as usize).match_cond("hello".as_bytes()) == Err(5)); assert!('l'.match_cond("hello".as_bytes()) == Ok(3)); assert!('w'.match_cond("hello".as_bytes()) == Err(5)); assert!("lo".match_cond("hello world".as_bytes()) == Ok(5)); assert!("world!".match_cond("hello world".as_bytes()) == Err(6)); assert!("".match_cond("hello".as_bytes()) == Err(0)); assert!("l".match_cond("hello".as_bytes()) == Ok(3)); }