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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
#![allow(unused_must_use)] use formatter::Formatter; use std::io; use std::io::Write; use types::EncodingType; use super::write_str; pub struct Protocol { out: Box<Write+'static>, last_expiry: Option<u64> } impl Protocol { pub fn new() -> Protocol { let out = Box::new(io::stdout()); Protocol { out: out, last_expiry: None } } } impl Protocol { fn emit(&mut self, args: Vec<&[u8]>) { write_str(&mut self.out, "*"); self.out.write_all(args.len().to_string().as_bytes()); write_str(&mut self.out, "\r\n"); for arg in args.iter() { write_str(&mut self.out, "$"); self.out.write_all(arg.len().to_string().as_bytes()); write_str(&mut self.out, "\r\n"); self.out.write_all(arg.as_slice()); write_str(&mut self.out, "\r\n"); } } fn pre_expire(&mut self, expiry: Option<u64>) { self.last_expiry = expiry } fn post_expire(&mut self, key: &[u8]) { if let Some(expire) = self.last_expiry { let expire = expire.to_string(); self.emit(vec!["EXPIREAT".as_bytes(), key, expire.as_bytes()]); self.last_expiry = None; } } } impl Formatter for Protocol { fn start_rdb(&mut self) { } fn end_rdb(&mut self) { } fn start_database(&mut self, db_number: u32) { let db = db_number.to_string(); self.emit(vec!["SELECT".as_bytes(), db.as_bytes()]) } fn set(&mut self, key: &[u8], value: &[u8], expiry: Option<u64>) { self.pre_expire(expiry); self.emit(vec!["SET".as_bytes(), key, value]); self.post_expire(key); } fn start_hash(&mut self, _key: &[u8], _length: u32, expiry: Option<u64>, _info: EncodingType) { self.pre_expire(expiry); } fn end_hash(&mut self, key: &[u8]) { self.post_expire(key); } fn hash_element(&mut self, key: &[u8], field: &[u8], value: &[u8]) { self.emit(vec!["HSET".as_bytes(), key, field, value]); } fn start_set(&mut self, _key: &[u8], _cardinality: u32, expiry: Option<u64>, _info: EncodingType) { self.pre_expire(expiry); } fn end_set(&mut self, key: &[u8]) { self.post_expire(key); } fn set_element(&mut self, key: &[u8], member: &[u8]) { self.emit(vec!["SADD".as_bytes(), key, member]); } fn start_list(&mut self, _key: &[u8], _length: u32, expiry: Option<u64>, _info: EncodingType) { self.pre_expire(expiry); } fn end_list(&mut self, key: &[u8]) { self.post_expire(key); } fn list_element(&mut self, key: &[u8], value: &[u8]) { self.emit(vec!["RPUSH".as_bytes(), key, value]); } fn start_sorted_set(&mut self, _key: &[u8], _length: u32, expiry: Option<u64>, _info: EncodingType) { self.pre_expire(expiry); } fn end_sorted_set(&mut self, key: &[u8]) { self.post_expire(key); } fn sorted_set_element(&mut self, key: &[u8], score: f64, member: &[u8]) { let score = score.to_string(); self.emit(vec!["ZADD".as_bytes(), key, score.as_bytes(), member]); } }