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
/*
    Appellation: config <module>
    Contrib: FL03 <jo3mccain@icloud.com>
    Description: ... Summary ...
*/
pub use self::{creds::*, regions::*, settings::*};

pub(crate) mod creds;
pub(crate) mod regions;

pub(crate) mod settings {
    use super::*;
    use s3::{creds::Credentials, Region};
    use scsys::prelude::{
        config::{Config, Environment},
        try_collect_config_files, AsyncResult, ConfigResult,
    };
    use serde::{Deserialize, Serialize};

    #[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
    pub struct GatewayConfig {
        pub access_key: String,
        pub(crate) secret_key: String,
        pub endpoint: String,
        pub region: String,
    }

    impl GatewayConfig {
        pub fn new(
            access_key: String,
            secret_key: String,
            endpoint: String,
            region: String,
        ) -> Self {
            Self {
                access_key,
                secret_key,
                endpoint,
                region,
            }
        }
        pub fn build() -> ConfigResult<Self> {
            let mut builder = Config::builder()
                .add_source(Environment::default().prefix("S3").separator("_"))
                .set_default("access_key", "")?
                .set_default("secret_key", "")?
                .set_default("endpoint", "https://gateway.storjshare.io")?
                .set_default("region", "us-east-1")?;

            if let Ok(v) = try_collect_config_files("**/*.config.*", false) {
                builder = builder.add_source(v);
            };
            if let Ok(v) = std::env::var("S3_ACCESS_KEY") {
                builder = builder.set_override("access_key", v)?;
            }
            if let Ok(v) = std::env::var("S3_SECRET_KEY") {
                builder = builder.set_override("secret_key", v)?;
            }

            builder.build()?.try_deserialize()
        }
        pub fn partial_env(
            access_key: Option<&str>,
            secret_key: Option<&str>,
            endpoint: String,
            region: String,
        ) -> AsyncResult<Self> {
            let access_key = std::env::var(access_key.unwrap_or("S3_ACCESS_KEY"))?;
            let secret_key = std::env::var(secret_key.unwrap_or("S3_SECRET_KEY"))?;
            Ok(Self::new(access_key, secret_key, endpoint, region))
        }
        pub fn credentials(&self) -> Credentials {
            let cred = GatewayCreds::new(self.access_key.clone(), self.secret_key.clone());
            cred.try_into().ok().unwrap()
        }
        pub fn region(&self) -> Region {
            Region::Custom {
                endpoint: self.endpoint.clone(),
                region: self.region.clone(),
            }
        }
    }

    impl std::convert::From<&GatewayCreds> for GatewayConfig {
        fn from(data: &GatewayCreds) -> Self {
            let region = S3Region::default();
            Self::new(
                data.access_key.clone(),
                data.secret_key.clone(),
                region.endpoint(),
                region.region(),
            )
        }
    }

    impl std::convert::From<&S3Region> for GatewayConfig {
        fn from(data: &S3Region) -> Self {
            let cred = GatewayCreds::default();
            Self::new(
                cred.access_key.clone(),
                cred.secret_key,
                data.endpoint(),
                data.region(),
            )
        }
    }

    impl Default for GatewayConfig {
        fn default() -> Self {
            Self::partial_env(
                None,
                None,
                "https://gateway.storjshare.io".to_string(),
                "us-east-1".to_string(),
            )
            .ok()
            .unwrap()
        }
    }
}