fastdfs 0.1.1

Rust client for FastDFS distributed file system
Documentation
# FastDFS Rust SDK

* support FastDFS `V5.04` ~ `V6.15.4`, or later.
* support IPv4 / IPv6 (since FastDFS V6.11)

[![github](https://img.shields.io/badge/Github-BrightX/fastdfs--rs-blue?logo=github)](https://github.com/BrightX/fastdfs-rs)
[![gitee](https://img.shields.io/badge/Gitee-BrightXu/fastdfs--rs-8da0cb?labelColor=C71D23&logo=gitee)](https://gitee.com/BrightXu/fastdfs-rs)
[![crate](https://img.shields.io/crates/v/fastdfs.svg?logo=rust)](https://crates.io/crates/fastdfs)
[![documentation](https://img.shields.io/badge/docs.rs-fastdfs-66c2a5?labelColor=555555&logo=docs.rs)](https://docs.rs/fastdfs)
[![minimum rustc 1.71](https://img.shields.io/badge/rustc-1.71+-red.svg?logo=rust)](https://rust-lang.github.io/rfcs/2495-min-rust-version.html)
![License](https://img.shields.io/crates/l/fastdfs)

## Install

```toml
# Cargo.toml
fastdfs = "0.1"

tokio = { version = "1", features = ["full"] }
```

## Usage

### 快速入门

通过 `ClientOptions` 配置一些选项,然后通过 `build` 方法构建一个 `FdfsClient`。
`FdfsClient` 内部使用了 `Arc` 智能指针,您可以在多线程的场景下十分廉价地进行 `clone` 来共享客户端和连接池。

```rust
use fastdfs::types::Metadata;
use fastdfs::{ClientOptions, FdfsClient, FileId, Result};

#[tokio::main]
async fn main() -> Result<()> {
    // configure your client
    let client = ClientOptions::new(vec!["127.0.0.1:22122"]).build()?;
    let data = br#"
# hello
> This is a text file, from buffer.
okay :-) .
"#;

    let mut metadata = Metadata::new();
    metadata.insert("filename".to_string(), "test.md".to_string());
    // upload your file from buffer
    let file_id = client
        .upload_file_buf(data, "md", Some(&metadata), false)
        .await?;
    println!("file_id: {:?}", file_id);

    // file exists
    let file_exists = client.file_exists(&file_id).await?;
    println!("file_exists: {}", file_exists);
    assert_eq!(file_exists, true, "file not exists");

    // query file metadata
    let file_metadata = client.get_metadata(&file_id).await?;
    println!("file_metadata: {:?}", file_metadata);

    // query file info
    let file_info = client.get_file_info(&file_id).await?;
    println!("file_info: {:?}", file_info);

    // download your file to buffer
    let data_buf = client.download_file_buf(&file_id, 0, 0).await?;
    println!("data_buf: {:?}", data_buf);
    assert_eq!(data_buf.as_ref(), data.as_ref(), "file data inconsistent");

    // delete your file
    client.delete_file(&file_id).await?;

    // The deleted file is no longer there
    let file_exists = client.file_exists(&file_id).await?;
    println!("file_exists: {}", file_exists);
    assert_eq!(file_exists, false, "file delete error");

    Ok(())
}
```

### ClientOptions 配置选项

| 参数                        | 说明                                                      | 默认值 |
| --------------------------- | --------------------------------------------------------- | :----: |
| tracker_addrs               | tracker server 服务地址列表,格式为 `host:port`           |        |
| max_connections             | 每个服务的最大连接数                                      |   10   |
| connect_timeout             | 建立连接的超时时间                                        |   5s   |
| network_timeout             | 网络I/O操作的超时时间                                     |  30s   |
| test_timeout                | 检测连接池中连接的超时时间                                |   5s   |
| time_between_eviction_runs  | 连接池 Evictor 线程运行间的睡眠持续时间                   |  120s  |
| min_evictable_idle_duration | 连接在池中空闲的最短时间,之后才有资格被 Evictor 线程淘汰 |  10s   |
| max_lifetime                | 设置单个连接的最大存活时间                                | 120min |
| idle_timeout                | 连接池中空闲连接的最大空闲时间                            |  60s   |
| retry_count                 | 失败操作的重试次数                                        |   3    |
| version                     | FastDFS 服务版本                                          | latest |

### FdfsClient 方法列表

| 序号 | 方法名称                     | 说明                                        |
| :--: | ---------------------------- | ------------------------------------------- |
|  1   | list_groups                  | 查询 group 状态信息                         |
|  2   | list_storages                | 查询 storage server 状态信息                |
|  3   | delete_storage               | 从 tracker server 中删除 storage server     |
|  4   | upload_file                  | 上传文件,从一个可读的异步 io 流            |
|  5   | upload_file_buf              | 上传文件,从一个 buf 缓冲区                 |
|  6   | upload_file_local            | 上传文件,从本地文件                        |
|  7   | download_file                | 下载文件,到一个可写的异步 io 流            |
|  8   | download_file_buf            | 下载文件,到一个 buf 缓冲区                 |
|  9   | download_file_local          | 下载文件,到本地文件                        |
|  10  | delete_file                  | 删除文件                                    |
|  11  | append_file                  | 追加文件,从一个可读的异步 io 流            |
|  12  | append_file_buf              | 追加文件,从一个 buf 缓冲区                 |
|  13  | append_file_local            | 追加文件,从本地文件                        |
|  14  | modify_file                  | 修改文件内容,从一个可读的异步 io 流        |
|  15  | modify_file_buf              | 修改文件内容,从一个 buf 缓冲区             |
|  16  | modify_file_local            | 修改文件内容,从本地文件                    |
|  17  | truncate_file                | 截断文件到指定大小                          |
|  18  | truncate_file0               | 截断文件大小到0                             |
|  19  | regenerate_appender_filename | appender类型文件改名为普通文件,自 v6.02 起 |
|  20  | set_metadata                 | 设置文件的 metadata                         |
|  21  | get_metadata                 | 获取文件的 metadata                         |
|  22  | get_file_info                | 获取文件信息,包括文件大小、时间戳、crc32等 |
|  23  | get_file_info_with_flag      | 获取文件信息,设置查询的flag,自 v6.15.1 起 |
|  24  | file_exists                  | 检查 storage server 上是否存在文件          |