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
use cosmwasm_std::{Addr, StdError, StdResult};

#[cosmwasm_schema::cw_serde]
#[non_exhaustive]
pub enum ModuleReference {
    /// Core Abstract Contracts
    Core(u64),
    /// Native Abstract Contracts
    Native(Addr),
    /// Installable apis
    Api(Addr),
    /// Installable apps
    App(u64),
    /// A stand-alone contract
    Standalone(u64),
}

impl ModuleReference {
    pub fn unwrap_core(&self) -> StdResult<u64> {
        match self {
            ModuleReference::Core(v) => Ok(*v),
            _ => Err(StdError::generic_err("Not a core module.")),
        }
    }

    pub fn unwrap_native(&self) -> StdResult<Addr> {
        match self {
            ModuleReference::Native(addr) => Ok(addr.clone()),
            _ => Err(StdError::generic_err("Not a native module.")),
        }
    }

    pub fn unwrap_api(&self) -> StdResult<Addr> {
        match self {
            ModuleReference::Api(addr) => Ok(addr.clone()),
            _ => Err(StdError::generic_err("Not an api module.")),
        }
    }

    pub fn unwrap_app(&self) -> StdResult<u64> {
        match self {
            ModuleReference::App(v) => Ok(*v),
            _ => Err(StdError::generic_err("Not an app module.")),
        }
    }

    pub fn unwrap_standalone(&self) -> StdResult<u64> {
        match self {
            ModuleReference::Standalone(v) => Ok(*v),
            _ => Err(StdError::generic_err("Not a standalone module.")),
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn core() {
        let core = ModuleReference::Core(1);
        assert_eq!(core.unwrap_core().unwrap(), 1);
        assert!(core.unwrap_native().is_err());
        assert!(core.unwrap_api().is_err());
        assert!(core.unwrap_app().is_err());
        assert!(core.unwrap_standalone().is_err());
    }
    #[test]
    fn native() {
        let native = ModuleReference::Native(Addr::unchecked("addr"));
        assert!(native.unwrap_core().is_err());
        assert_eq!(native.unwrap_native().unwrap(), Addr::unchecked("addr"));
        assert!(native.unwrap_api().is_err());
        assert!(native.unwrap_app().is_err());
        assert!(native.unwrap_standalone().is_err());
    }

    #[test]
    fn api() {
        let api = ModuleReference::Api(Addr::unchecked("addr"));
        assert!(api.unwrap_core().is_err());
        assert!(api.unwrap_native().is_err());
        assert_eq!(api.unwrap_api().unwrap(), Addr::unchecked("addr"));
        assert!(api.unwrap_app().is_err());
        assert!(api.unwrap_standalone().is_err());
    }

    #[test]
    fn app() {
        let app = ModuleReference::App(1);
        assert!(app.unwrap_core().is_err());
        assert!(app.unwrap_native().is_err());
        assert!(app.unwrap_api().is_err());
        assert_eq!(app.unwrap_app().unwrap(), 1);
        assert!(app.unwrap_standalone().is_err());
    }

    #[test]
    fn standalone() {
        let standalone = ModuleReference::Standalone(1);
        assert!(standalone.unwrap_core().is_err());
        assert!(standalone.unwrap_native().is_err());
        assert!(standalone.unwrap_api().is_err());
        assert!(standalone.unwrap_app().is_err());
        assert_eq!(standalone.unwrap_standalone().unwrap(), 1);
    }
}