// SPDX-FileCopyrightText: © Matteo Settenvini // SPDX-License-Identifier: EUPL-1.2 use { object_store::{ObjectStore, aws}, rocket::serde::Deserialize, serde::de::Error, }; #[derive(Deserialize)] #[serde(crate = "rocket::serde")] pub struct Settings { #[serde(deserialize_with = "deserialize_s3_bucket")] pub s3_bucket: Box, } fn deserialize_s3_bucket<'de, D>(deserializer: D) -> Result, D::Error> where D: serde::Deserializer<'de>, { let config = S3Config::deserialize(deserializer)?; config.try_into().map_err(D::Error::custom) } #[derive(Deserialize)] pub struct S3Config { pub name: String, pub endpoint: String, pub region: String, #[serde(default)] pub path_style: bool, pub access_key_id: String, pub secret_access_key: String, } impl TryInto> for S3Config { type Error = anyhow::Error; fn try_into(self) -> Result, Self::Error> { // TODO: support object stores other than than AWS let object_store = aws::AmazonS3Builder::new() .with_region(self.region) .with_endpoint(&self.endpoint) .with_bucket_name(&self.name) .with_access_key_id(self.access_key_id) .with_secret_access_key(self.secret_access_key) .with_virtual_hosted_style_request(!self.path_style) .build()?; log::info!( "Serving contents from bucket {} at {}", self.endpoint, self.name, ); Ok(Box::new(object_store)) } }