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
// This file is part of Gear.

// Copyright (C) 2022-2024 Gear Technologies Inc.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0

// This program 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.

// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.

//! Module for map's key generation primitives.
//!
//! Key generator primitives might be used to prevent
//! manual specifying of the key for cases,
//! when data stored in map.

use crate::Origin;
use core::marker::PhantomData;
use gear_core::{
    ids::{MessageId, ProgramId},
    message::{StoredDispatch, UserStoredMessage},
};

/// Represents logic of providing key as specified
/// (associated) type for given as specified
/// (associated) type value by reference.
pub trait KeyFor {
    /// Generated key type.
    type Key;
    /// Value over which key should be generated type.
    type Value;

    /// Generates key for given by reference Value.
    fn key_for(value: &Self::Value) -> Self::Key;
}

/// Key generator for `gear`'s mailbox implementation.
pub struct MailboxKeyGen<T>(PhantomData<T>);

// `MailboxKeyGen` stores `StoredMessage` under it's
// `MessageId` id parameter and the generic `T: Origin`
// (represented with `Substrate`'s 32-byte `AccountId`)
// destination parameter.
impl<T: Origin> KeyFor for MailboxKeyGen<T> {
    type Key = (T, MessageId);
    type Value = UserStoredMessage;

    fn key_for(value: &Self::Value) -> Self::Key {
        (value.destination().cast(), value.id())
    }
}

/// Key generator for `gear`'s message queue implementation.
pub struct QueueKeyGen;

// `QueueKeyGen` stores `StoredDispatch` under
// it's `MessageId` id parameter.
impl KeyFor for QueueKeyGen {
    type Key = MessageId;
    type Value = StoredDispatch;

    fn key_for(value: &Self::Value) -> Self::Key {
        value.id()
    }
}

/// Key generator for `gear`'s waitlist implementation.
pub struct WaitlistKeyGen;

// `WaitlistKeyGen` stores `StoredDispatch` under it's destination
// `ProgramId` and `MessageId` id parameters.
impl KeyFor for WaitlistKeyGen {
    type Key = (ProgramId, MessageId);
    type Value = StoredDispatch;

    fn key_for(value: &Self::Value) -> Self::Key {
        (value.destination(), value.id())
    }
}