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
125
126
127
128
129
130
131
132
133
134
//! Config Store for Compute.

pub(crate) mod handle;

use handle::ConfigStoreHandle;
pub use handle::{LookupError, OpenError};

/// Maximum Edge Config Store value size.
///
/// > Config Store containers, item keys, and their values have specific limits. Config Store
/// > containers are limited to 100_000 items. Config Store item keys are limited to 256 characters and
/// > their values are limited to 8000 characters.
///
/// This constant is used as the default buffer size for config store values when using the
/// high-level config store API.
///
const MAX_LEN: usize = 8000;

/// A Compute Config Store.
pub struct ConfigStore {
    handle: ConfigStoreHandle,
}

impl ConfigStore {
    /// Open a config store, given its name.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// # use fastly::ConfigStore;
    /// let merriam = ConfigStore::open("merriam webster");
    /// let oed = ConfigStore::open("oxford english config store");
    /// ```
    pub fn open(name: &str) -> Self {
        let handle = match ConfigStoreHandle::open(name) {
            Ok(h) if h.is_valid() => h,
            Ok(_) => panic!("could not open config store `{}`", name),
            Err(e) => panic!("could not open config store `{}`: {}", name, e),
        };

        Self { handle }
    }

    /// Try to open a config store, given its name.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// # use fastly::config_store::*;
    /// let merriam = ConfigStore::try_open("merriam webster").unwrap();
    /// ```
    pub fn try_open(name: &str) -> Result<Self, OpenError> {
        ConfigStoreHandle::open(name).map(|handle| Self { handle })
    }

    /// Lookup a value in this config store.
    ///
    /// If successful, this function returns `Some(_)` if an entry was found, or `None` if no entry
    /// with the given key was found.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// # use fastly::ConfigStore;
    /// # let config_store = ConfigStore::open("test config store");
    /// #
    /// assert_eq!(
    ///      config_store.get("bread"),
    ///      Some(String::from("a usually baked and leavened food")),
    /// );
    /// assert_eq!(
    ///     config_store.get("freedom"),
    ///     Some(String::from("the absence of necessity, coercion, or constraint")),
    /// );
    ///
    /// // Otherwise, `get` will return nothing.
    /// assert!(config_store.get("zzzzz").is_none());
    /// ```
    ///
    /// # Panics
    ///
    /// This may panic for any of the reasons that [`ConfigStore::try_get`] would return an error.
    pub fn get(&self, key: &str) -> Option<String> {
        self.try_get(key)
            .unwrap_or_else(|e| panic!("lookup for key `{}` failed: {}", key, e))
    }

    /// Try to lookup a value in this Config Store.
    ///
    /// If successful, this function returns `Ok(Some(_))` if an entry was found, or `Ok(None)` if
    /// no entry with the given key was found. This function returns `Err(_)` if the lookup failed.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// # use fastly::ConfigStore;
    /// # let config_store = ConfigStore::open("test config store");
    /// #
    /// assert_eq!(
    ///      config_store.try_get("bread").unwrap(),
    ///      Some(String::from("a usually baked and leavened food")),
    /// );
    /// assert_eq!(
    ///     config_store.try_get("freedom").unwrap(),
    ///     Some(String::from("the absence of necessity, coercion, or constraint")),
    /// );
    ///
    /// // Otherwise, `try_get` will return nothing.
    /// assert!(config_store.try_get("zzzzz").unwrap().is_none());
    /// ```
    pub fn try_get(&self, key: &str) -> Result<Option<String>, LookupError> {
        self.handle.get(key, MAX_LEN)
    }

    /// Return true if the config_store contains an entry with the given key.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// # use fastly::ConfigStore;
    /// # let config_store = ConfigStore::open("test config_store");
    /// #
    /// assert!(config_store.contains("key"));
    /// ```
    ///
    /// # Panics
    ///
    /// This may panic for any of the reasons that [`ConfigStore::try_get`] would return an error.
    pub fn contains(&self, key: &str) -> bool {
        self.handle
            .contains(key)
            .unwrap_or_else(|e| panic!("lookup for key `{}` failed: {}", key, e))
    }
}