Compare commits

..
Author SHA1 Message Date
phoenix f406ed1961 Delete object (#3)
labyrinth release Tagging / release (push) Successful in 1m15s
simodels Build / build (push) Successful in 1m25s
simodels Build / Test Suite (push) Successful in 1m35s
simodels Build / Check (push) Successful in 1m38s
simodels Build / Rustfmt (push) Successful in 2m33s
simodels Build / Clippy (push) Successful in 2m49s
Reviewed-on: #3
2026-08-11 10:39:12 -04:00
phoenix 6ed1d00a32 Download (#2)
simodels Build / Test Suite (push) Successful in 1m18s
simodels Build / build (push) Successful in 1m21s
simodels Build / Check (push) Successful in 1m25s
labyrinth release Tagging / release (push) Successful in 1m46s
simodels Build / Rustfmt (push) Successful in 1m54s
simodels Build / Clippy (push) Successful in 2m36s
Reviewed-on: #2
2026-08-10 17:41:33 -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 171 additions and 25 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.4"
dependencies = [
"aws-config",
"aws-sdk-s3",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "labyrinth"
version = "0.0.1"
version = "0.0.4"
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,
+74 -22
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),
@@ -23,32 +47,13 @@ pub enum Error {
}
impl Labyrinth {
/// Upload object to the bucket
pub async fn upload(
&self,
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 config = aws_config::load_from_env().await;
let client = aws_sdk_s3::Client::new(&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,
@@ -72,4 +77,51 @@ impl Labyrinth {
Err(err) => Err(Error::Info(err.to_string())),
}
}
/// Download object from the bucket
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())),
}
}
/// Delete an object from the bucket
pub async fn delete(
&self,
file_key: &str,
) -> Result<aws_sdk_s3::operation::delete_object::DeleteObjectOutput, Error> {
let client = init_client(&self.config).await;
match client
.delete_object()
.bucket(self.config.bucket.clone())
.key(file_key)
.send()
.await
{
Ok(response) => Ok(response),
Err(err) => Err(Error::Info(err.to_string())),
}
}
}