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
//                              Næ§@@@ÑÉ©
//                        æ@@@@@@@@@@@@@@@@@@
//                    Ñ@@@@?.?@@@@@@@@@@@@@@@@@@@N
//                 ¶@@@@@?^%@@.=@@@@@@@@@@@@@@@@@@@@
//               N@@@@@@@?^@@@»^@@@@@@@@@@@@@@@@@@@@@@
//               @@@@@@@@?^@@@».............?@@@@@@@@@É
//              Ñ@@@@@@@@?^@@@@@@@@@@@@@@@@@@'?@@@@@@@@Ñ
//              @@@@@@@@@?^@@@»..............»@@@@@@@@@@
//              @@@@@@@@@?^@@@»^@@@@@@@@@@@@@@@@@@@@@@@@
//              @@@@@@@@@?^ë@@&.@@@@@@@@@@@@@@@@@@@@@@@@
//               @@@@@@@@?^´@@@o.%@@@@@@@@@@@@@@@@@@@@©
//                @@@@@@@?.´@@@@@ë.........*.±@@@@@@@æ
//                 @@@@@@@@?´.I@@@@@@@@@@@@@@.&@@@@@N
//                  N@@@@@@@@@@ë.*=????????=?@@@@@Ñ
//                    @@@@@@@@@@@@@@@@@@@@@@@@@@@¶
//                        É@@@@@@@@@@@@@@@@Ѷ
//                             Næ§@@@ÑÉ©

// Copyright 2020 Chris D'Costa
// This file is part of Totem Live Accounting.
// Authors:
// - Félix Daudré-Vignier   email: felix@totemaccounting.com
// - Chris D'Costa          email: chris.dcosta@totemaccounting.com

// Totem is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Totem is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Totem.  If not, see <http://www.gnu.org/licenses/>.

use codec::{Decode, Encode, EncodeLike, FullCodec, FullEncode};
use frame_support::{dispatch::DispatchResultWithPostInfo, storage::StorageMap};

/// Adds behavior to `StorageMap`s.
pub trait StorageMapExt<K, V>
where
    Self: StorageMap<K, V>,
    K: FullEncode + Encode + EncodeLike,
    V: FullCodec + Decode + FullEncode + Encode + EncodeLike,
{
    /// If the key exists in the map, modifies it with the provided function,
    /// otherwise, an error is returned.
    fn mutate_or_err<KeyArg: EncodeLike<K>, F: FnOnce(&mut V)>(
        key: KeyArg,
        f: F,
    ) -> DispatchResultWithPostInfo {
        Self::mutate_exists(key, |option| match option.as_mut() {
            Some(value) => Ok(f(value).into()),
            None => Err("Cannot recover the value".into()),
        })
    }
}

impl<T, K, V> StorageMapExt<K, V> for T
where
    T: StorageMap<K, V>,
    K: FullEncode + Encode + EncodeLike,
    V: FullCodec + Decode + FullEncode + Encode + EncodeLike,
{
}