fix(smarts3): replace TypeScript server with Rust-powered core and IPC bridge

This commit is contained in:
2026-02-13 13:59:44 +00:00
parent 54a0c2fb65
commit 65eb266983
32 changed files with 4083 additions and 3182 deletions

70
rust/src/s3_error.rs Normal file
View File

@@ -0,0 +1,70 @@
use hyper::{Response, StatusCode};
use http_body_util::Full;
use bytes::Bytes;
#[derive(Debug, thiserror::Error)]
#[error("S3Error({code}): {message}")]
pub struct S3Error {
pub code: String,
pub message: String,
pub status: StatusCode,
}
impl S3Error {
pub fn new(code: &str, message: &str, status: StatusCode) -> Self {
Self {
code: code.to_string(),
message: message.to_string(),
status,
}
}
pub fn no_such_key() -> Self {
Self::new("NoSuchKey", "The specified key does not exist.", StatusCode::NOT_FOUND)
}
pub fn no_such_bucket() -> Self {
Self::new("NoSuchBucket", "The specified bucket does not exist", StatusCode::NOT_FOUND)
}
pub fn bucket_not_empty() -> Self {
Self::new("BucketNotEmpty", "The bucket you tried to delete is not empty", StatusCode::CONFLICT)
}
pub fn access_denied() -> Self {
Self::new("AccessDenied", "Access Denied", StatusCode::FORBIDDEN)
}
pub fn no_such_upload() -> Self {
Self::new("NoSuchUpload", "The specified upload does not exist", StatusCode::NOT_FOUND)
}
pub fn invalid_part_number() -> Self {
Self::new("InvalidPartNumber", "Part number must be between 1 and 10000", StatusCode::BAD_REQUEST)
}
pub fn internal_error(msg: &str) -> Self {
Self::new("InternalError", msg, StatusCode::INTERNAL_SERVER_ERROR)
}
pub fn invalid_request(msg: &str) -> Self {
Self::new("InvalidRequest", msg, StatusCode::BAD_REQUEST)
}
pub fn to_xml(&self) -> String {
format!(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Error><Code>{}</Code><Message>{}</Message></Error>",
self.code, self.message
)
}
pub fn to_response(&self, request_id: &str) -> Response<Full<Bytes>> {
let xml = self.to_xml();
Response::builder()
.status(self.status)
.header("content-type", "application/xml")
.header("x-amz-request-id", request_id)
.body(Full::new(Bytes::from(xml)))
.unwrap()
}
}