asyncio/streams/
match_cond.rs1pub trait MatchCondition : Send + 'static {
2 fn match_cond(&mut self, buf: &[u8]) -> Result<usize, usize>;
3}
4
5impl MatchCondition for usize {
6 fn match_cond(&mut self, buf: &[u8]) -> Result<usize, usize> {
7 if buf.len() >= *self {
8 Ok(*self)
9 } else {
10 *self -= buf.len();
11 Err(buf.len())
12 }
13 }
14}
15
16impl MatchCondition for u8 {
17 fn match_cond(&mut self, buf: &[u8]) -> Result<usize, usize> {
18 if let Some(len) = buf.iter().position(|&x| x == *self) {
19 Ok(len+1)
20 } else {
21 Err(buf.len())
22 }
23 }
24}
25
26impl MatchCondition for &'static [u8] {
27 fn match_cond(&mut self, buf: &[u8]) -> Result<usize, usize> {
28 let mut cur = 0;
29 if !self.is_empty() {
30 let head = self[0];
31 let tail = &self[1..];
32 let mut it = buf.iter();
33 while let Some(mut len) = it.position(|&x| x == head) {
34 len += cur + 1;
35 let buf = &buf[len..];
36 if buf.len() < tail.len() {
37 return Err(len - 1);
38 } else if buf.starts_with(tail) {
39 return Ok(len + tail.len());
40 }
41 cur = len;
42 it = buf.iter();
43 }
44 cur = buf.len();
45 }
46 Err(cur)
47 }
48}
49
50impl MatchCondition for char {
51 fn match_cond(&mut self, buf: &[u8]) -> Result<usize, usize> {
52 (*self as u8).match_cond(buf)
53 }
54}
55
56impl MatchCondition for &'static str {
57 fn match_cond(&mut self, buf: &[u8]) -> Result<usize, usize> {
58 self.as_bytes().match_cond(buf)
59 }
60}
61
62#[test]
63fn test_match_cond() {
64 assert!((5 as usize).match_cond("hello".as_bytes()) == Ok(5));
65 assert!((5 as usize).match_cond("hello world".as_bytes()) == Ok(5));
66 assert!((10 as usize).match_cond("hello".as_bytes()) == Err(5));
67 assert!('l'.match_cond("hello".as_bytes()) == Ok(3));
68 assert!('w'.match_cond("hello".as_bytes()) == Err(5));
69 assert!("lo".match_cond("hello world".as_bytes()) == Ok(5));
70 assert!("world!".match_cond("hello world".as_bytes()) == Err(6));
71 assert!("".match_cond("hello".as_bytes()) == Err(0));
72 assert!("l".match_cond("hello".as_bytes()) == Ok(3));
73}