Unverified Commit 4039538d authored by Nugine's avatar Nugine
Browse files

s3s: request

parent 5a589acb
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ pub fn codegen(ops: &Operations, rust_types: &RustTypes, g: &mut Codegen) {
        "use crate::conv::{try_from_aws, try_into_aws};",
        "",
        "use s3s::S3;",
        "use s3s::S3Request;",
        "use s3s::S3Result;",
        "",
        "use tracing::debug;",
@@ -29,9 +30,12 @@ pub fn codegen(ops: &Operations, rust_types: &RustTypes, g: &mut Codegen) {
        let s3s_input = f!("s3s::dto::{}", op.input);
        let s3s_output = f!("s3s::dto::{}", op.output);

        g.ln("#[tracing::instrument(skip(self, input))]");
        g.ln(f!("async fn {method_name}(&self, input: {s3s_input}) -> S3Result<{s3s_output}> {{"));
        g.ln("#[tracing::instrument(skip(self, req))]");
        g.ln(f!(
            "async fn {method_name}(&self, req: S3Request<{s3s_input}>) -> S3Result<{s3s_output}> {{"
        ));

        g.ln("let input = req.input;");
        g.ln("debug!(?input);");

        if op.smithy_input == "Unit" {
+4 −3
Original line number Diff line number Diff line
@@ -337,7 +337,7 @@ fn codegen_op_http_de(op: &Operation, rust_types: &RustTypes, g: &mut Codegen) {

                if op.name == "PutObject" {
                    // POST object
                    g.ln("if let Some(m) = req.extensions.remove::<http::Multipart>() {");
                    g.ln("if let Some(m) = req.s3ext.multipart.take() {");
                    g.ln("    return Self::deserialize_http_multipart(req, m);");
                    g.ln("}");
                    g.lf();
@@ -507,7 +507,7 @@ fn codegen_op_http_de_multipart(op: &Operation, rust_types: &RustTypes, g: &mut
        "let bucket = http::unwrap_bucket(req);",
        "let key = http::parse_field_value(&m, \"key\")?.ok_or_else(|| invalid_request!(\"missing key\"))?;",
        "",
        "let vec_stream = req.extensions.remove::<crate::stream::VecByteStream>().expect(\"missing vec stream\");",
        "let vec_stream = req.s3ext.vec_stream.take().expect(\"missing vec stream\");",
        "",
        "let content_length = i64::try_from(vec_stream.exact_remaining_length()).map_err(|e|s3_error!(e, InvalidArgument, \"content-length overflow\"))?;",
        "",
@@ -600,7 +600,8 @@ fn codegen_op_http_call(op: &Operation, g: &mut Codegen) {
    let method = op.name.to_snake_case();

    g.ln("let input = Self::deserialize_http(req)?;");
    g.ln(f!("let result = s3.{method}(input).await;"));
    g.ln("let req = super::build_s3_request(input, req);");
    g.ln(f!("let result = s3.{method}(req).await;"));

    g.ln("let res = match result {");
    g.ln("Ok(output) => Self::serialize_http(output)?,");
+4 −1
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ pub fn codegen(ops: &Operations, g: &mut Codegen) {
        "",
        "use crate::dto::*;",
        "use crate::error::S3Result;",
        "use crate::request::S3Request;",
        "",
        "/// An async trait which represents the S3 API",
        "#[async_trait::async_trait]",
@@ -20,9 +21,11 @@ pub fn codegen(ops: &Operations, g: &mut Codegen) {

    for op in ops.values() {
        let method_name = op.name.to_snake_case();
        let input = &op.input;
        let output = &op.output;

        codegen_doc(op.doc.as_deref(), g);
        g.ln(f!("async fn {method_name}(&self, _input: {}) -> S3Result<{}> {{", op.input, op.output));
        g.ln(f!("async fn {method_name}(&self, _req: S3Request<{input}>) -> S3Result<{output}> {{"));
        g.ln(f!("Err(s3_error!(NotImplemented, \"{} is not implemented yet\"))", op.name));
        g.ln("}");
        g.lf();
+319 −186

File changed.

Preview size limit exceeded, changes collapsed.

+35 −19
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@ use crate::utils::*;

use s3s::dto::*;
use s3s::s3_error;
use s3s::S3Request;
use s3s::S3Result;
use s3s::S3;

@@ -27,7 +28,8 @@ use tracing::debug;
#[async_trait::async_trait]
impl S3 for FileSystem {
    #[tracing::instrument]
    async fn create_bucket(&self, input: CreateBucketInput) -> S3Result<CreateBucketOutput> {
    async fn create_bucket(&self, req: S3Request<CreateBucketInput>) -> S3Result<CreateBucketOutput> {
        let input = req.input;
        let path = self.get_bucket_path(&input.bucket)?;

        if path.exists() {
@@ -41,7 +43,8 @@ impl S3 for FileSystem {
    }

    #[tracing::instrument]
    async fn copy_object(&self, input: CopyObjectInput) -> S3Result<CopyObjectOutput> {
    async fn copy_object(&self, req: S3Request<CopyObjectInput>) -> S3Result<CopyObjectOutput> {
        let input = req.input;
        let (bucket, key) = match input.copy_source {
            CopySource::AccessPoint { .. } => return Err(s3_error!(NotImplemented)),
            CopySource::Bucket { ref bucket, ref key, .. } => (bucket, key),
@@ -83,14 +86,16 @@ impl S3 for FileSystem {
    }

    #[tracing::instrument]
    async fn delete_bucket(&self, input: DeleteBucketInput) -> S3Result<DeleteBucketOutput> {
    async fn delete_bucket(&self, req: S3Request<DeleteBucketInput>) -> S3Result<DeleteBucketOutput> {
        let input = req.input;
        let path = self.get_bucket_path(&input.bucket)?;
        try_!(fs::remove_dir_all(path).await);
        Ok(DeleteBucketOutput {})
    }

    #[tracing::instrument]
    async fn delete_object(&self, input: DeleteObjectInput) -> S3Result<DeleteObjectOutput> {
    async fn delete_object(&self, req: S3Request<DeleteObjectInput>) -> S3Result<DeleteObjectOutput> {
        let input = req.input;
        let path = self.get_object_path(&input.bucket, &input.key)?;
        if input.key.ends_with('/') {
            let mut dir = try_!(fs::read_dir(&path).await);
@@ -106,7 +111,8 @@ impl S3 for FileSystem {
    }

    #[tracing::instrument]
    async fn delete_objects(&self, input: DeleteObjectsInput) -> S3Result<DeleteObjectsOutput> {
    async fn delete_objects(&self, req: S3Request<DeleteObjectsInput>) -> S3Result<DeleteObjectsOutput> {
        let input = req.input;
        let mut objects: Vec<(PathBuf, String)> = Vec::new();
        for object in input.delete.objects {
            let path = self.get_object_path(&input.bucket, &object.key)?;
@@ -135,7 +141,8 @@ impl S3 for FileSystem {
    }

    #[tracing::instrument]
    async fn get_bucket_location(&self, input: GetBucketLocationInput) -> S3Result<GetBucketLocationOutput> {
    async fn get_bucket_location(&self, req: S3Request<GetBucketLocationInput>) -> S3Result<GetBucketLocationOutput> {
        let input = req.input;
        let path = self.get_bucket_path(&input.bucket)?;

        if !path.exists() {
@@ -147,7 +154,8 @@ impl S3 for FileSystem {
    }

    #[tracing::instrument]
    async fn get_object(&self, input: GetObjectInput) -> S3Result<GetObjectOutput> {
    async fn get_object(&self, req: S3Request<GetObjectInput>) -> S3Result<GetObjectOutput> {
        let input = req.input;
        let object_path = self.get_object_path(&input.bucket, &input.key)?;

        let mut file = fs::File::open(&object_path).await.map_err(|e| s3_error!(e, NoSuchKey))?;
@@ -208,7 +216,8 @@ impl S3 for FileSystem {
    }

    #[tracing::instrument]
    async fn head_bucket(&self, input: HeadBucketInput) -> S3Result<HeadBucketOutput> {
    async fn head_bucket(&self, req: S3Request<HeadBucketInput>) -> S3Result<HeadBucketOutput> {
        let input = req.input;
        let path = self.get_bucket_path(&input.bucket)?;

        if !path.exists() {
@@ -219,7 +228,8 @@ impl S3 for FileSystem {
    }

    #[tracing::instrument]
    async fn head_object(&self, input: HeadObjectInput) -> S3Result<HeadObjectOutput> {
    async fn head_object(&self, req: S3Request<HeadObjectInput>) -> S3Result<HeadObjectOutput> {
        let input = req.input;
        let path = self.get_object_path(&input.bucket, &input.key)?;

        if !path.exists() {
@@ -246,7 +256,7 @@ impl S3 for FileSystem {
    }

    #[tracing::instrument]
    async fn list_buckets(&self, _: ListBucketsInput) -> S3Result<ListBucketsOutput> {
    async fn list_buckets(&self, _: S3Request<ListBucketsInput>) -> S3Result<ListBucketsOutput> {
        let mut buckets: Vec<Bucket> = Vec::new();
        let mut iter = try_!(fs::read_dir(&self.root).await);
        while let Some(entry) = try_!(iter.next_entry().await) {
@@ -279,8 +289,8 @@ impl S3 for FileSystem {
    }

    #[tracing::instrument]
    async fn list_objects(&self, input: ListObjectsInput) -> S3Result<ListObjectsOutput> {
        let v2 = self.list_objects_v2(input.into()).await?;
    async fn list_objects(&self, req: S3Request<ListObjectsInput>) -> S3Result<ListObjectsOutput> {
        let v2 = self.list_objects_v2(req.map_input(Into::into)).await?;

        let output = ListObjectsOutput {
            contents: v2.contents,
@@ -295,7 +305,8 @@ impl S3 for FileSystem {
    }

    #[tracing::instrument]
    async fn list_objects_v2(&self, input: ListObjectsV2Input) -> S3Result<ListObjectsV2Output> {
    async fn list_objects_v2(&self, req: S3Request<ListObjectsV2Input>) -> S3Result<ListObjectsV2Output> {
        let input = req.input;
        let path = self.get_bucket_path(&input.bucket)?;

        if path.exists().not() {
@@ -360,7 +371,8 @@ impl S3 for FileSystem {
    }

    #[tracing::instrument]
    async fn put_object(&self, input: PutObjectInput) -> S3Result<PutObjectOutput> {
    async fn put_object(&self, req: S3Request<PutObjectInput>) -> S3Result<PutObjectOutput> {
        let input = req.input;
        if let Some(ref storage_class) = input.storage_class {
            let is_valid = ["STANDARD", "REDUCED_REDUNDANCY"].contains(&storage_class.as_str());
            if !is_valid {
@@ -417,7 +429,8 @@ impl S3 for FileSystem {
    }

    #[tracing::instrument]
    async fn create_multipart_upload(&self, input: CreateMultipartUploadInput) -> S3Result<CreateMultipartUploadOutput> {
    async fn create_multipart_upload(&self, req: S3Request<CreateMultipartUploadInput>) -> S3Result<CreateMultipartUploadOutput> {
        let input = req.input;
        let upload_id = uuid::Uuid::new_v4().to_string();

        let output = CreateMultipartUploadOutput {
@@ -431,13 +444,13 @@ impl S3 for FileSystem {
    }

    #[tracing::instrument]
    async fn upload_part(&self, input: UploadPartInput) -> S3Result<UploadPartOutput> {
    async fn upload_part(&self, req: S3Request<UploadPartInput>) -> S3Result<UploadPartOutput> {
        let UploadPartInput {
            body,
            upload_id,
            part_number,
            ..
        } = input;
        } = req.input;

        let body = body.ok_or_else(|| s3_error!(IncompleteBody))?;

@@ -467,14 +480,17 @@ impl S3 for FileSystem {
    }

    #[tracing::instrument]
    async fn complete_multipart_upload(&self, input: CompleteMultipartUploadInput) -> S3Result<CompleteMultipartUploadOutput> {
    async fn complete_multipart_upload(
        &self,
        req: S3Request<CompleteMultipartUploadInput>,
    ) -> S3Result<CompleteMultipartUploadOutput> {
        let CompleteMultipartUploadInput {
            multipart_upload,
            bucket,
            key,
            upload_id,
            ..
        } = input;
        } = req.input;

        let Some(multipart_upload) = multipart_upload else { return Err(s3_error!(InvalidPart)) };

Loading