cw_clearable/
lib.rs

1use cosmwasm_std::{Addr, Api, StdResult};
2
3/// A type representing a value that can either be cleared or set with a value of type `C`.
4/// ```
5/// use cosmwasm_std::{StdResult, Response, DepsMut};
6/// use cw_storage_plus::Item;
7/// use cw_clearable::Clearable;
8///
9/// const FOO: Item<Option<u32>> = Item::new("foo");
10///
11/// pub fn update_config(deps: DepsMut, foo: Option<Clearable<u32>>) -> StdResult<Response>{
12///     if let Some(foo) = foo {
13///         FOO.save(deps.storage, &foo.into());
14///     }
15///     Ok(Response::new())
16/// }
17/// ```
18#[cosmwasm_schema::cw_serde]
19pub enum Clearable<C> {
20    /// Clear the current state.
21    Clear,
22    /// Set state with a value of type `C`.
23    Set(C),
24}
25
26impl<C> Clearable<C> {
27    pub fn new(value: C) -> Clearable<C> {
28        Clearable::Set(value)
29    }
30
31    pub fn new_opt(value: C) -> Option<Clearable<C>> {
32        Some(Clearable::Set(value))
33    }
34}
35
36impl Clearable<String> {
37    pub fn check(&self, api: &dyn Api) -> StdResult<Clearable<Addr>> {
38        match self {
39            Clearable::Clear => Ok(Clearable::Clear),
40            Clearable::Set(human) => Ok(Clearable::Set(api.addr_validate(human)?)),
41        }
42    }
43}
44
45// Get new value for this item
46impl<C> Into<Option<C>> for Clearable<C> {
47    fn into(self) -> Option<C> {
48        match self {
49            Clearable::Clear => None,
50            Clearable::Set(val) => Some(val),
51        }
52    }
53}
54
55#[cfg(test)]
56mod test {
57    use super::*;
58    use cosmwasm_std::testing::MockStorage;
59    use cw_storage_plus::Item;
60
61    const FOO: Item<Option<u32>> = Item::new("foo");
62
63    #[test]
64    fn clear() {
65        let mut storage = MockStorage::new();
66        FOO.save(&mut storage, &Some(0u32)).unwrap();
67
68        let clearable: Clearable<u32> = Clearable::Clear;
69        FOO.save(&mut storage, &clearable.into()).unwrap();
70
71        let foo = FOO.load(&storage).unwrap();
72        assert_eq!(foo, None);
73    }
74
75    #[test]
76    fn set() {
77        let mut storage = MockStorage::new();
78        FOO.save(&mut storage, &Some(0u32)).unwrap();
79
80        let clearable: Clearable<u32> = Clearable::Set(42);
81        FOO.save(&mut storage, &clearable.into()).unwrap();
82
83        let foo = FOO.load(&storage).unwrap();
84        assert_eq!(foo, Some(42));
85    }
86
87    #[test]
88    fn constructors() {
89        let clearable_new = Clearable::new(5u32);
90        assert_eq!(clearable_new, Clearable::Set(5u32));
91
92        let clearable_new_opt = Clearable::new_opt(6u32);
93        assert_eq!(clearable_new_opt, Some(Clearable::Set(6u32)))
94    }
95}