🏡 index : ~doyle/shorty.git

use anyhow::Context;
use async_trait::async_trait;
use rusoto_core::{
    credential::{AwsCredentials, CredentialsError, ProvideAwsCredentials},
    HttpClient, Region,
};
use rusoto_s3::S3Client;
use serde::Deserialize;

pub const CONFIG_PATH: &'static str = ".config/shorty.toml";

#[derive(Deserialize)]
pub struct Config {
    pub s3: S3Config,
}

impl Config {
    pub async fn load() -> anyhow::Result<Self> {
        let home = std::env::var("HOME").context("$HOME missing")?;
        let path = std::path::PathBuf::from(home).join(CONFIG_PATH);
        let config = tokio::fs::read(path)
            .await
            .with_context(|| format!("couldn't load config from {}", CONFIG_PATH))?;
        Ok(toml::from_slice(&config)?)
    }
}

#[derive(Deserialize)]
pub struct S3Config {
    pub endpoint: String,
    pub bucket: String,
    pub key: String,
    pub secret: String,
}

pub struct Credentials {
    key: String,
    secret: String,
}

#[async_trait]
impl ProvideAwsCredentials for Credentials {
    async fn credentials(&self) -> Result<AwsCredentials, CredentialsError> {
        Ok(AwsCredentials::new(&self.key, &self.secret, None, None))
    }
}

pub fn s3_client(key: String, secret: String, endpoint: String) -> anyhow::Result<S3Client> {
    Ok(S3Client::new_with(
        HttpClient::new()?,
        Credentials { key, secret },
        Region::Custom {
            name: "us-east-1".to_string(),
            endpoint,
        },
    ))
}