10 releases

0.2.4 Dec 26, 2023
0.2.3 May 23, 2023
0.2.2 Dec 22, 2022
0.2.1 Nov 1, 2022
0.1.2 Jun 9, 2022

#42 in HTTP client

Download history 89/week @ 2023-12-22 8/week @ 2023-12-29 18/week @ 2024-01-05 21/week @ 2024-01-12 21/week @ 2024-01-19 20/week @ 2024-01-26 20/week @ 2024-02-02 21/week @ 2024-02-09 13/week @ 2024-02-16 142/week @ 2024-02-23 77/week @ 2024-03-01 50/week @ 2024-03-08 39/week @ 2024-03-15 53/week @ 2024-03-22 88/week @ 2024-03-29 63/week @ 2024-04-05

246 downloads per month
Used in 16 crates (9 directly)

MIT license

19KB
427 lines

Qiniu Resource Storage SDK for Rust

Run Test Cases GitHub release MIT licensed

概要

Qiniu SDK for Rust 包含以下特性:

  • 通过提供多个不同的 Crate,为不同层次的开发都提供了方便易用的编程接口。
  • 同时提供阻塞 IO 接口和基于 Async/Await 的异步 IO 接口。
  • 提供大量的可供二次开发的 Trait,方便灵活定制,例如 HTTP 客户端提供了 ureqreqwestisahc 三种不同的库实现,也可以基于 qiniu-http 自行定制开发接入其他 HTTP 客户端实现;又例如 DNS 客户端提供了 libcc-arestrust-dns 三种不同的库实现,也可以基于 Resolver 自行定制开发接入其他 DNS 客户端实现。

安装

Qiniu SDK for Rust 包含以下 Crates:

Crate 链接 文档 描述
qiniu-etag docs.rs Etag 算法库,实现七牛 Etag 算法
qiniu-credential docs.rs 七牛认证库,实现七牛认证接口以及签名相关算法
qiniu-upload-token docs.rs 七牛上传凭证,实现七牛上传策略和上传凭证接口以及相关算法
qiniu-http docs.rs 七牛客户端 HTTP 接口,为不同的 HTTP 客户端实现提供相同的基础接口
qiniu-ureq docs.rs 基于 Ureq 库实现七牛客户端 HTTP 接口,对于使用 qiniu-http-requestqiniu-apisqiniu-objects-managerqiniu-upload-manager 的用户,可以直接启用 ureq 功能,将默认使用该 HTTP 客户端实现。需要注意的是,如果需要使用异步接口,则不能选择 ureq
qiniu-isahc docs.rs 基于 Isahc 库实现七牛客户端 HTTP 接口,对于使用 qiniu-http-requestqiniu-apisqiniu-objects-managerqiniu-upload-manager 的用户,可以直接启用 isahc 功能,将默认使用该 HTTP 客户端实现
qiniu-reqwest docs.rs 基于 Reqwest 库实现七牛客户端 HTTP 接口,对于使用 qiniu-http-requestqiniu-apisqiniu-objects-managerqiniu-upload-manager 的用户,可以直接启用 reqwest 功能,将默认使用该 HTTP 客户端实现
qiniu-http-client docs.rs 基于 qiniu-http 提供具有重试功能的 HTTP 客户端
qiniu-apis docs.rs 实现七牛 API 调用客户端接口
qiniu-objects-manager docs.rs 实现七牛对象相关管理接口,包含对象的列举和操作
qiniu-upload-manager docs.rs 实现七牛对象上传功能
qiniu-download-manager docs.rs 实现七牛对象下载功能
qiniu-sdk docs.rs 七牛 SDK 入口

代码示例

以下所有代码示例都以 qiniu-sdk 作为入口。

客户端上传凭证(需要依赖 qiniu-sdk 启用 upload-token 功能)

客户端(移动端或者Web端)上传文件的时候,需要从客户自己的业务服务器获取上传凭证,而这些上传凭证是通过服务端的 SDK 来生成的,然后通过客户自己的业务API分发给客户端使用。根据上传的业务需求不同,七牛云 Rust SDK 支持丰富的上传凭证生成方式。

简单上传的凭证

最简单的上传凭证只需要 access keysecret keybucket 就可以。

use qiniu_sdk::upload_token::{UploadPolicy, credential::Credential, prelude::*};
use std::time::Duration;

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let credential = Credential::new(access_key, secret_key);
let upload_token = UploadPolicy::new_for_bucket(bucket_name, Duration::from_secs(3600))
    .build_token(credential, Default::default())?;
println!("{}", upload_token);

覆盖上传的凭证

覆盖上传除了需要简单上传所需要的信息之外,还需要想进行覆盖的对象名称 object name,这个对象名称同时是客户端上传代码中指定的对象名称,两者必须一致。

use qiniu_sdk::upload_token::{UploadPolicy, credential::Credential, prelude::*};
use std::time::Duration;

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let object_name = "object name";
let credential = Credential::new(access_key, secret_key);
let upload_token = UploadPolicy::new_for_object(bucket_name, object_name, Duration::from_secs(3600))
    .build_token(credential, Default::default())?;
println!("{}", upload_token);

自定义上传回复的凭证

默认情况下,文件上传到七牛之后,在没有设置 return_body 或者回调相关的参数情况下,七牛返回给上传端的回复格式为 hashkey,例如:

{"hash":"Ftgm-CkWePC9fzMBTRNmPMhGBcSV","key":"qiniu.jpg"}

有时候我们希望能自定义这个返回的 JSON 格式的内容,可以通过设置 return_body 参数来实现,在 return_body 中,我们可以使用七牛支持的魔法变量和自定义变量。

use qiniu_sdk::upload_token::{UploadPolicy, credential::Credential, prelude::*};
use std::time::Duration;

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let object_name = "object name";
let credential = Credential::new(access_key, secret_key);
let upload_token = UploadPolicy::new_for_object(bucket_name, object_name, Duration::from_secs(3600))
    .return_body("{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"bucket\":\"$(bucket)\",\"fsize\":$(fsize)}")
    .build_token(credential, Default::default())?;
println!("{}", upload_token);

则文件上传到七牛之后,收到的回复内容如下:

{"key":"qiniu.jpg","hash":"Ftgm-CkWePC9fzMBTRNmPMhGBcSV","bucket":"if-bc","fsize":39335}

带回调业务服务器的凭证

上面生成的自定义上传回复的上传凭证适用于上传端(无论是客户端还是服务端)和七牛服务器之间进行直接交互的情况下。在客户端上传的场景之下,有时候客户端需要在文件上传到七牛之后,从业务服务器获取相关的信息,这个时候就要用到七牛的上传回调及相关回调参数的设置。

use qiniu_sdk::upload_token::{UploadPolicy, credential::Credential, prelude::*};
use std::time::Duration;

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let object_name = "object name";
let credential = Credential::new(access_key, secret_key);
let upload_token = UploadPolicy::new_for_object(bucket_name, object_name, Duration::from_secs(3600))
    .callback(&["http://api.example.com/qiniu/upload/callback"], "", "{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"bucket\":\"$(bucket)\",\"fsize\":$(fsize)}", "application/json")
    .build_token(credential, Default::default())?;
println!("{}", upload_token);

在使用了上传回调的情况下,客户端收到的回复就是业务服务器响应七牛的JSON格式内容。 通常情况下,我们建议使用 application/json 格式来设置 callback_body,保持数据格式的统一性。实际情况下,callback_body 也支持 application/x-www-form-urlencoded 格式来组织内容,这个主要看业务服务器在接收到 callback_body 的内容时如何解析。例如:

use qiniu_sdk::upload_token::{UploadPolicy, credential::Credential, prelude::*};
use std::time::Duration;

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let object_name = "object name";
let credential = Credential::new(access_key, secret_key);
let upload_token = UploadPolicy::new_for_object(bucket_name, object_name, Duration::from_secs(3600))
    .callback(&["http://api.example.com/qiniu/upload/callback"], "", "key=$(key)&hash=$(etag)&bucket=$(bucket)&fsize=$(fsize)", "")
    .build_token(credential, Default::default())?;
println!("{}", upload_token);

服务端直传(需要依赖 qiniu-sdk 启用 upload 功能)

服务端直传是指客户利用七牛服务端 SDK 从服务端直接上传文件到七牛云,交互的双方一般都在机房里面,所以服务端可以自己生成上传凭证,然后利用 SDK 中的上传逻辑进行上传,最后从七牛云获取上传的结果,这个过程中由于双方都是业务服务器,所以很少利用到上传回调的功能,而是直接自定义 return_body 来获取自定义的回复内容。

文件上传

最简单的就是上传本地文件,直接指定文件的完整路径即可上传。

use qiniu_sdk::upload::{
    apis::credential::Credential, AutoUploader, AutoUploaderObjectParams, UploadManager,
    UploadTokenSigner,
};
use std::{time::Duration};

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let object_name = "object name";
let credential = Credential::new(access_key, secret_key);
let upload_manager = UploadManager::builder(UploadTokenSigner::new_credential_provider(
    credential,
    bucket_name,
    Duration::from_secs(3600),
))
.build();
let mut uploader: AutoUploader = upload_manager.auto_uploader();

let params = AutoUploaderObjectParams::builder().object_name(object_name).file_name(object_name).build();
uploader.upload_path("/home/qiniu/test.png", params)?;

在这个场景下,AutoUploader 会自动根据文件尺寸判定是否启用断点续上传,如果文件较大,上传了一部分时因各种原因从而中断,再重新执行相同的代码时,SDK 会尝试找到先前没有完成的上传任务,从而继续进行上传。

字节数组上传 / 数据流上传

可以支持将内存中的字节数组或实现了 std::io::Read 的实例上传到空间中。

use qiniu_sdk::upload::{
    apis::credential::Credential, AutoUploader, AutoUploaderObjectParams, UploadManager,
    UploadTokenSigner,
};
use std::{io::Cursor, time::Duration};

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let object_name = "object name";
let credential = Credential::new(access_key, secret_key);
let upload_manager = UploadManager::builder(UploadTokenSigner::new_credential_provider(
    credential,
    bucket_name,
    Duration::from_secs(3600),
))
.build();
let mut uploader: AutoUploader = upload_manager.auto_uploader();

let params = AutoUploaderObjectParams::builder().object_name(object_name).file_name(object_name).build();
uploader.upload_reader(Cursor::new("hello qiniu cloud"), params)?;

自定义参数上传

use qiniu_sdk::upload::{
    apis::credential::Credential, AutoUploader, AutoUploaderObjectParams, UploadManager, UploadTokenSigner,
};
use std::{io::Cursor, time::Duration};

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let object_name = "object name";
let credential = Credential::new(access_key, secret_key);
let upload_manager = UploadManager::builder(
    UploadTokenSigner::new_credential_provider_builder(credential, bucket_name, Duration::from_secs(3600))
        .on_policy_generated(|builder| {
            builder
                .return_body("{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"fname\":\"$(x:fname)\",\"age\",$(x:age)}");
        })
        .build(),
)
.build();
let mut uploader: AutoUploader = upload_manager.auto_uploader();

let params = AutoUploaderObjectParams::builder()
    .object_name(object_name)
    .file_name(object_name)
    .insert_custom_var("fname", "123.jpg")
    .insert_custom_var("age", "20")
    .build();
uploader.upload_path("/home/qiniu/test.mp4", params)?;

私有云上传

use qiniu_sdk::upload::{
    apis::{
        credential::Credential,
        http_client::{EndpointsBuilder, HttpClient},
    },
    AutoUploader, AutoUploaderObjectParams, UploadManager, UploadTokenSigner,
};
use std::{time::Duration};

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let object_name = "object name";
let credential = Credential::new(access_key, secret_key);
let upload_manager = UploadManager::builder(UploadTokenSigner::new_credential_provider(
    credential,
    bucket_name,
    Duration::from_secs(3600),
))
.uc_endpoints(
    EndpointsBuilder::default()
        .add_preferred_endpoint("ucpub-qos.pocdemo.qiniu.io".into()) // 私有云存储空间管理服务域名,可以添加多个
        .build(),
)
.use_https(false) // 私有云普遍使用 HTTP 协议,而 SDK 则默认为 HTTPS 协议
.build();
let mut uploader: AutoUploader = upload_manager.auto_uploader();

let params = AutoUploaderObjectParams::builder().object_name(object_name).file_name(object_name).build();
uploader.upload_path("/home/qiniu/test.png", params)?;

下载文件(需要依赖 qiniu-sdk 启用 download 功能)

文件下载分为公开空间的文件下载和私有空间的文件下载。

公开空间

use qiniu_sdk::download::{DownloadManager, StaticDomainsUrlsGenerator};

let object_name = "公司/存储/qiniu.jpg";
let domain = "devtools.qiniu.com";
let path = "/home/user/qiniu.jpg";
let download_manager = DownloadManager::new(
    StaticDomainsUrlsGenerator::builder(domain)
        .use_https(false) // 设置为 HTTP 协议
        .build(),
);
download_manager
    .download(object_name)?
    .to_path(path)?;

私有空间

use qiniu_sdk::download::{apis::credential::Credential, DownloadManager, StaticDomainsUrlsGenerator, UrlsSigner};

let access_key = "access key";
let secret_key = "secret key";
let object_name = "公司/存储/qiniu.jpg";
let domain = "devtools.qiniu.com";
let path = "/home/user/qiniu.jpg";
let download_manager = DownloadManager::new(UrlsSigner::new(
    Credential::new(access_key, secret_key),
    StaticDomainsUrlsGenerator::builder(domain)
        .use_https(false) // 设置为 HTTP 协议
        .build(),
));
download_manager
    .download(object_name)?
    .to_path(path)?;

资源管理(需要依赖 qiniu-sdk 启用 objects 功能)

获取文件信息

use qiniu_sdk::objects::{apis::credential::Credential, ObjectsManager};

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let object_name = "object name";
let credential = Credential::new(access_key, secret_key);
let object_manager = ObjectsManager::new(credential);
let bucket = object_manager.bucket(bucket_name);

let response = bucket.stat_object(object_name).call()?;
let entry = response.into_body();
println!("{}", entry.get_hash_as_str());
println!("{}", entry.get_size_as_u64());
println!("{}", entry.get_mime_type_as_str());
println!("{}", entry.get_put_time_as_u64());

修改文件类型

use qiniu_sdk::objects::{apis::credential::Credential, ObjectsManager};

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let object_name = "object name";
let credential = Credential::new(access_key, secret_key);
let object_manager = ObjectsManager::new(credential);
let bucket = object_manager.bucket(bucket_name);

bucket
    .modify_object_metadata(object_name, mime::APPLICATION_JSON)
    .call()?;

移动或重命名文件

移动操作本身支持移动文件到相同,不同空间中,在移动的同时也可以支持文件重命名。唯一的限制条件是,移动的源空间和目标空间必须在同一个机房。

use qiniu_sdk::objects::{apis::credential::Credential, ObjectsManager};

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let object_name = "object name";
let to_bucket_name = "to bucket name";
let to_object_name = "new object name";
let credential = Credential::new(access_key, secret_key);
let object_manager = ObjectsManager::new(credential);
let bucket = object_manager.bucket(bucket_name);

bucket
    .move_object_to(object_name, to_bucket_name, to_object_name);
    .call()?;

复制文件副本

文件的复制和文件移动其实操作一样,主要的区别是移动后源文件不存在了,而复制的结果是源文件还存在,只是多了一个新的文件副本。

use qiniu_sdk::objects::{apis::credential::Credential, ObjectsManager};

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let object_name = "object name";
let to_bucket_name = "to bucket name";
let to_object_name = "new object name";
let credential = Credential::new(access_key, secret_key);
let object_manager = ObjectsManager::new(credential);
let bucket = object_manager.bucket(bucket_name);

bucket
    .copy_object_to(object_name, to_bucket_name, to_object_name);
    .call()?;

删除空间中的文件

use qiniu_sdk::objects::{apis::credential::Credential, ObjectsManager};

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let object_name = "object name";
let credential = Credential::new(access_key, secret_key);
let object_manager = ObjectsManager::new(credential);
let bucket = object_manager.bucket(bucket_name);

bucket
    .delete_object(object_name);
    .call()?;

设置或更新文件的生存时间

可以给已经存在于空间中的文件设置文件生存时间,或者更新已设置了生存时间但尚未被删除的文件的新的生存时间。

use qiniu_sdk::objects::{apis::credential::Credential, AfterDays, ObjectsManager};

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let object_name = "object name";
let credential = Credential::new(access_key, secret_key);
let object_manager = ObjectsManager::new(credential);
let bucket = object_manager.bucket(bucket_name);

bucket
    .modify_object_life_cycle(object_name)
    .delete_after_days(AfterDays::new(10))
    .call()?;

获取空间文件列表

use qiniu_sdk::objects::{apis::credential::Credential, ObjectsManager};

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let credential = Credential::new(access_key, secret_key);
let object_manager = ObjectsManager::new(credential);
let bucket = object_manager.bucket(bucket_name);

let mut iter = bucket.list().iter();
while let Some(entry) = iter.next() {
    let entry = entry?;
    println!(
        "{}\n  hash: {}\n  size: {}\n  mime type: {}",
        entry.get_key_as_str(),
        entry.get_hash_as_str(),
        entry.get_size_as_u64(),
        entry.get_mime_type_as_str(),
    );
}

私有云中获取空间文件列表

use qiniu_sdk::objects::{
    apis::{
        credential::Credential,
        http_client::{EndpointsBuilder, HttpClient},
    },
    ObjectsManager,
};
use std::net::Ipv4Addr;

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let credential = Credential::new(access_key, secret_key);
let object_manager = ObjectsManager::builder(credential)
    .uc_endpoints(
        EndpointsBuilder::default()
            .add_preferred_endpoint("ucpub-qos.pocdemo.qiniu.io".into()) // 私有云存储空间管理服务域名,可以添加多个
            .build(),
    )
    .use_https(false) // 私有云普遍使用 HTTP 协议,而 SDK 则默认为 HTTPS 协议
    .build();
let bucket = object_manager.bucket(bucket_name);

let mut iter = bucket.list().iter();
while let Some(entry) = iter.next() {
    let entry = entry?;
    println!(
        "{}\n  hash: {}\n  size: {}\n  mime type: {}",
        entry.get_key_as_str(),
        entry.get_hash_as_str(),
        entry.get_size_as_u64(),
        entry.get_mime_type_as_str(),
    );
}

资源管理批量操作(需要依赖 qiniu-sdk 启用 objects 功能)

批量获取文件信息

use qiniu_sdk::objects::{apis::credential::Credential, ObjectsManager};

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let credential = Credential::new(access_key, secret_key);
let object_manager = ObjectsManager::new(credential);
let bucket = object_manager.bucket(bucket_name);
let mut ops = bucket.batch_ops();
ops.add_operation(bucket.stat_object("qiniu.jpg"));
ops.add_operation(bucket.stat_object("qiniu.mp4"));
ops.add_operation(bucket.stat_object("qiniu.png"));

let mut iter = ops.call();
while let Some(result) = iter.next() {
    match result {
        Ok(entry) => {
            println!(
                "hash: {:?}\n  size: {:?}\n  mime type: {:?}",
                entry.get_hash_as_str(),
                entry.get_size_as_u64(),
                entry.get_mime_type_as_str(),
            );
        }
        Err(err) => {
            println!("{:?}", err);
        }
    }
}

批量修改文件类型

use qiniu_sdk::objects::{apis::credential::Credential, ObjectsManager};

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let credential = Credential::new(access_key, secret_key);
let object_manager = ObjectsManager::new(credential);
let bucket = object_manager.bucket(bucket_name);
let mut ops = bucket.batch_ops();
ops.add_operation(bucket.modify_object_metadata("qiniu.jpg", mime::IMAGE_JPEG));
ops.add_operation(bucket.modify_object_metadata("qiniu.png", mime::IMAGE_PNG));
ops.add_operation(bucket.modify_object_metadata("qiniu.mp4", "video/mp4".parse()?));

let mut iter = ops.call();
while let Some(result) = iter.next() {
    match result {
        Ok(_) => {
            println!("Ok");
        }
        Err(err) => {
            println!("{:?}", err);
        }
    }
}

批量删除文件

use qiniu_sdk::objects::{apis::credential::Credential, ObjectsManager};

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let credential = Credential::new(access_key, secret_key);
let object_manager = ObjectsManager::new(credential);
let bucket = object_manager.bucket(bucket_name);
let mut ops = bucket.batch_ops();
ops.add_operation(bucket.delete_object("qiniu.jpg"));
ops.add_operation(bucket.delete_object("qiniu.png"));
ops.add_operation(bucket.delete_object("qiniu.mp4"));

let mut iter = ops.call();
while let Some(result) = iter.next() {
    match result {
        Ok(_) => {
            println!("Ok");
        }
        Err(err) => {
            println!("{:?}", err);
        }
    }
}

批量移动或重命名文件

use qiniu_sdk::objects::{apis::credential::Credential, ObjectsManager};

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let credential = Credential::new(access_key, secret_key);
let object_manager = ObjectsManager::new(credential);
let bucket = object_manager.bucket(bucket_name);
let mut ops = bucket.batch_ops();
ops.add_operation(bucket.move_object_to("qiniu.jpg", bucket_name, "qiniu.jpg.move"));
ops.add_operation(bucket.move_object_to("qiniu.png", bucket_name, "qiniu.png.move"));
ops.add_operation(bucket.move_object_to("qiniu.mp4", bucket_name, "qiniu.mp4.move"));

let mut iter = ops.call();
while let Some(result) = iter.next() {
    match result {
        Ok(_) => {
            println!("Ok");
        }
        Err(err) => {
            println!("{:?}", err);
        }
    }
}

批量复制文件

use qiniu_sdk::objects::{apis::credential::Credential, ObjectsManager};

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let credential = Credential::new(access_key, secret_key);
let object_manager = ObjectsManager::new(credential);
let bucket = object_manager.bucket(bucket_name);
let mut ops = bucket.batch_ops();
ops.add_operation(bucket.copy_object_to("qiniu.jpg", bucket_name, "qiniu.jpg.move"));
ops.add_operation(bucket.copy_object_to("qiniu.png", bucket_name, "qiniu.png.move"));
ops.add_operation(bucket.copy_object_to("qiniu.mp4", bucket_name, "qiniu.mp4.move"));

let mut iter = ops.call();
while let Some(result) = iter.next() {
    match result {
        Ok(_) => {
            println!("Ok");
        }
        Err(err) => {
            println!("{:?}", err);
        }
    }
}

批量解冻归档存储类型文件

use qiniu_sdk::objects::{apis::credential::Credential, ObjectsManager};

let access_key = "access key";
let secret_key = "secret key";
let bucket_name = "bucket name";
let credential = Credential::new(access_key, secret_key);
let object_manager = ObjectsManager::new(credential);
let bucket = object_manager.bucket(bucket_name);
let mut ops = bucket.batch_ops();
ops.add_operation(bucket.restore_archived_object("qiniu.jpg", 7));
ops.add_operation(bucket.restore_archived_object("qiniu.png", 7));
ops.add_operation(bucket.restore_archived_object("qiniu.mp4", 7));

let mut iter = ops.call();
while let Some(result) = iter.next() {
    match result {
        Ok(_) => {
            println!("Ok");
        }
        Err(err) => {
            println!("{:?}", err);
        }
    }
}

最低支持的 Rust 版本(MSRV)

  • 1.70.0

编码规范

  • 通过 cargo clippy 检查,并经过 rustfmt 格式化。
  • 所有阻塞操作都提供异步无阻塞版本。
  • 竭力避免 unsafe 代码。
  • 所有公开的 trait 都可以通过 prelude 模块自动导入。
  • 公开接口中如果要求传入或返回某个第三方库的类型,则该类型也必须公开导出。

联系我们

  • 如果需要帮助,请提交工单(在portal右侧点击咨询和建议提交工单,或者直接向 support@qiniu.com 发送邮件)
  • 如果有什么问题,可以到问答社区提问,问答社区
  • 更详细的文档,见官方文档站
  • 如果发现了bug, 欢迎提交 Issue
  • 如果有功能需求,欢迎提交 Issue
  • 如果要提交代码,欢迎提交 Pull Request
  • 欢迎关注我们的微信 微博,及时获取动态信息。

代码许可

This project is licensed under the MIT license.


lib.rs:

qiniu-etag

七牛实用工具库

仅供七牛 SDK 内部使用,接口不保证总是兼容变更

Dependencies

~415–700KB
~15K SLoC