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
114
115
116
117
118
119
120
121
122
123
124
use std::collections::{HashMap, HashSet};

/// An opaque type that stores data.
///
/// This is used by both red and red-server independently, kind of like a
/// singleton instance; however, you can make as many instances as you need.
#[derive(Debug)]
pub struct State {
    store: HashMap<String, String>,
    set: HashSet<String>,
}

/// Implements functionality for `Store`. At time of writing this documentation,
/// it supports a few "commands" in a similar way to Redis: I've only
/// implemented the ones I actually need.
///
/// Full 1:1 mapping of Redis commands is not a goal, but it would be nice to
/// keep following their spec closely.
impl State {
    /// Instantiate `State` by calling this function.
    ///
    /// # Example
    ///
    /// ```
    /// use red::State;
    ///
    /// let mut state = State::new();
    /// ```
    pub fn new() -> Self {
        State {
            store: HashMap::new(),
            set: HashSet::new(),
        }
    }

    /// Get the value of key.
    ///
    /// # Example
    ///
    /// ```
    /// // The return value of the function is an option
    /// # let mut state = red::State::new();
    /// let value = state.get("someKey");
    ///
    /// // Pattern match to retrieve the value
    /// match value {
    ///     // The key was present
    ///     Some(v) => println!("Value: {}", v),
    ///     // The key was not present
    ///     None    => println!("Nope"),
    /// }
    /// ```
    pub fn get(&mut self, key: &str) -> Option<&String> {
        self.store.get(key)
    }

    /// Add a new member to the set.
    /// If the member is already in the set, it will be ignored.
    ///
    /// # Example
    ///
    /// ```
    /// # let mut state = red::State::new();
    /// state.sadd("BOOMBAYAH".to_string());
    ///
    /// assert_eq!("BOOMBAYAH", state.smembers().next().unwrap());
    /// ```
    pub fn sadd(&mut self, member: String) -> bool {
        self.set.insert(member)
    }

    /// Returns an iterator to retrieve some or all the members of the set.
    /// The retrieval order is completely arbitrary.
    ///
    /// # Example
    ///
    /// ```
    /// # let mut state = red::State::new();
    /// state.sadd("foo".to_string());
    /// state.sadd("bar".to_string());
    ///
    /// // Will print in an arbitrary order.
    /// for member in state.smembers() {
    ///     println!("{}", member);
    /// }
    /// ```
    /// For more detail about iterators, see the
    /// [official docs](https://doc.rust-lang.org/std/iter/index.html).
    pub fn smembers(&mut self) -> impl Iterator<Item = &String> {
        return self.set.iter();
    }

    /// Remove the specified member from the set.
    ///
    /// Returns true if the member was in the set; false otherwise.
    ///
    /// # Example
    ///
    /// ```
    /// # let mut state = red::State::new();
    /// state.sadd("mittsies".to_string());
    ///
    /// assert_eq!(state.srem("mittsies"), true);
    /// assert_eq!(state.srem("mittsies"), false);
    /// ```
    pub fn srem(&mut self, member: &str) -> bool {
        self.set.remove(member)
    }

    /// Set key to hold the specified value. If the key already holds a value,
    /// it is overwritten.
    ///
    /// # Example
    ///
    /// ```
    /// # let mut state = red::State::new();
    /// state.set("someKey".to_string(), "Blade".to_string());
    ///
    /// assert_eq!(state.get("someKey").unwrap(), "Blade");
    /// ```
    pub fn set(&mut self, key: String, value: String) {
        self.store.insert(key, value);
    }
}