Compare commits

..
Author SHA1 Message Date
phoenix 2b6127f6a6 Code formatting
simodels Build / Rustfmt (pull_request) Successful in 1m54s
labyrinth release Tagging / release (pull_request) Successful in 1m54s
simodels Build / Clippy (pull_request) Successful in 2m30s
simodels Build / Test Suite (pull_request) Successful in 2m52s
simodels Build / build (pull_request) Successful in 2m53s
simodels Build / Check (pull_request) Successful in 2m56s
2026-08-10 17:16:18 -04:00
phoenix 8464401337 Adding code to download from the bucket 2026-08-10 17:14:48 -04:00
phoenix 7db41e190e Adding license
labyrinth release Tagging / release (pull_request) Successful in 3m4s
simodels Build / Check (pull_request) Successful in 3m27s
simodels Build / Test Suite (pull_request) Successful in 3m32s
simodels Build / Rustfmt (pull_request) Successful in 4m42s
simodels Build / Clippy (pull_request) Failing after 4m52s
simodels Build / build (pull_request) Successful in 5m8s
2026-08-10 16:51:59 -04:00
phoenix 966aad363b ci: Adding workflow 2026-08-10 16:51:52 -04:00
phoenix a3901c7a8e Try it (#1)
labyrinth release Tagging / release (push) Successful in 31s
labyrinth release Tagging / release (pull_request) Successful in 1m47s
Reviewed-on: #1
2026-08-08 13:27:10 -04:00
6 changed files with 150 additions and 30 deletions
+73
View File
@@ -0,0 +1,73 @@
name: simodels Build
on:
push:
branches:
- main
pull_request:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
check:
name: Check
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.97
- uses: Swatinem/rust-cache@v2
- run: cargo check
test:
name: Test Suite
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.97
- uses: Swatinem/rust-cache@v2
- run: cargo test
fmt:
name: Rustfmt
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.97
- uses: Swatinem/rust-cache@v2
- run: rustup component add rustfmt
- run: cargo fmt --all -- --check
clippy:
name: Clippy
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.97
- uses: Swatinem/rust-cache@v2
- run: rustup component add clippy
- run: cargo clippy -- -D warnings
build:
name: build
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.97
- uses: Swatinem/rust-cache@v2
- run: cargo build
Generated
+1 -1
View File
@@ -1370,7 +1370,7 @@ dependencies = [
[[package]]
name = "labyrinth"
version = "0.0.1"
version = "0.0.2"
dependencies = [
"aws-config",
"aws-sdk-s3",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "labyrinth"
version = "0.0.1"
version = "0.0.2"
edition = "2024"
license = "MIT"
description = "Library for managing soaricarus storage"
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Kun Deng
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+1 -1
View File
@@ -1,4 +1,4 @@
#[derive(Default)]
#[derive(Debug, Default)]
pub struct Config {
pub url: String,
pub bucket: String,
+53 -27
View File
@@ -2,7 +2,7 @@ pub mod config;
use aws_sdk_s3::config::{Credentials, Region};
#[derive(Default)]
#[derive(Debug, Default)]
pub struct Data {
pub filepath: String,
pub raw_data: Vec<u8>,
@@ -16,6 +16,30 @@ pub async fn load_data(filepath: &str) -> Result<Vec<u8>, std::io::Error> {
tokio::fs::read(filepath).await
}
pub async fn init_client(config: &config::Config) -> aws_sdk_s3::Client {
let credentials = Credentials::new(
config.access_key_id.clone(),
config.secret_key.clone(),
None,
None,
"maze",
);
let region = Region::new(config.region.to_string());
let config = aws_config::from_env()
.region(region)
.credentials_provider(credentials)
.endpoint_url(config.url.clone())
.load()
.await;
let s3_config = aws_sdk_s3::config::Builder::from(&config)
.force_path_style(true)
.build();
aws_sdk_s3::Client::from_conf(s3_config)
}
#[derive(Debug)]
pub enum Error {
Info(String),
@@ -28,32 +52,7 @@ impl Labyrinth {
file_key: &str,
data: &Data,
) -> Result<aws_sdk_s3::operation::put_object::PutObjectOutput, Error> {
// 1. Create credentials
let credentials = Credentials::new(
self.config.access_key_id.clone(),
self.config.secret_key.clone(),
None, // session_token - None for long-term credentials
None, // expires_after - None for long-term credentials
"maze", // provider_name - just a label
);
// 2. Create region
let region = Region::new(self.config.region.to_string());
let config = aws_config::from_env()
.region(region)
.credentials_provider(credentials)
.endpoint_url(self.config.url.clone())
.load()
.await;
let s3_config = aws_sdk_s3::config::Builder::from(&config)
.force_path_style(true) // 👈 CRITICAL for Garage/MinIO/LocalStack
.build();
// let config = aws_config::load_from_env().await;
// let client = aws_sdk_s3::Client::new(&config);
let client = aws_sdk_s3::Client::from_conf(s3_config);
let client = init_client(&self.config).await;
let data_content = if data.raw_data.is_empty() {
match load_data(&data.filepath).await {
Ok(content) => content,
@@ -77,4 +76,31 @@ impl Labyrinth {
Err(err) => Err(Error::Info(err.to_string())),
}
}
pub async fn download(&self, file_key: &str) -> Result<Vec<u8>, Error> {
let client = init_client(&self.config).await;
match client
.get_object()
.bucket(self.config.bucket.clone())
.key(file_key)
.send()
.await
{
Ok(response) => {
let body = response.body;
// Get the body as ByteStream
match body.collect().await {
Ok(data) => {
let bytes = data.into_bytes();
let raw_data = bytes.to_vec();
Ok(raw_data)
}
Err(err) => Err(Error::Info(err.to_string())),
}
}
Err(err) => Err(Error::Info(err.to_string())),
}
}
}