fusio-log 0.3.6

The append only log implementations.
Documentation

# Fusio Log
`fusio-log` is an append-only log library for Rust. Leveraging [fusio](https://github.com/tonbo-io/fusio), `fusio-log` supports various backends like disk, wasm, and S3.

For those unfamiliar with the database, the key difference between `fusio-log` and other "logging" crates is that `fusio-log` not only supports writing logs through the `write` and `write_batch` methods, but also allows reading logs via the `recover` method.

This crate is designed to build database components like [write-ahead logging](https://en.wikipedia.org/wiki/Write-ahead_logging) or metadata storage, `fusio-log` supports transactional write/read via `write_batch`, ensuring that logs in the same batch are recovered together.

For further more, please read https://datatechnologytoday.wordpress.com/2014/02/10/the-log-is-the-database/.


## Usage

1. Define data structure.
```rust
struct User {
    id: u64,
    name: String,
    email: Option<String>,
}
```

2. Implement `Encode` and `Decode` trait for it.
3. Start to use fusio-log.

```rust
#[tokio::main]
async fn main() {
    let temp_dir = TempDir::new().unwrap();
    let path = Path::from_filesystem_path(temp_dir.path())
        .unwrap()
        .child("log");

    let mut logger = Options::new(path).build::<User>().await.unwrap();
    logger.write(&User {id: 1, name: "fusio-log".to_string(), None}).await.unwrap();
    logger.write_batch([
        User {id: 2, name: "fusio".to_string(), "contact@tonbo.io"}
        User {id: 3, name: "tonbo".to_string(), None}
    ].into_iter()).await.unwrap();

    logger.flush().await.unwrap();
    logger.close().await.unwrap();

}
```

Recover from log file:
```rust
let stream = Options::new(path)
    .recover::<User>()
    .await
    .unwrap();
while let Ok(users) = stream.try_next().await {
    match users {
        Some(users) => {
            for user in users {
                println("{}" user.id)
            }
        };
        None => println();
    }
}
```

### Use with S3
```rust

let path = Path::from_url_path("log").unwrap();
let option = Options::new(path).fs(FsOptions::S3 {
    bucket: "data".to_string(),
    credential: Some(fusio::remotes::aws::AwsCredential {
        key_id: "key_id".to_string(),
        secret_key: "secret_key".to_string(),
        token: None,
    }),
    endpoint: None,
    region: Some("region".to_string()),
    sign_payload: None,
    checksum: None,
});

let mut logger = option.build::<User>().await.unwrap();
logger
    .write(&User {
        id: 100,
        name: "Name".to_string(),
        email: None,
    })
    .await
    .unwrap();
```

### Use in Wasm

Please make sure disable default features and enable `web` feature.

```toml
fusio-log = {git = "https://github.com/tonbo-io/fusio-log", default-features = false, features = ["bytes", "web"]}
```

Then, use `Path::from_opfs_path` to replace `Path::from_filesystem_path`
```rust
let temp_dir = TempDir::new().unwrap();
let path = Path::from_opfs_path(temp_dir.path())
    .unwrap()
    .child("log");

let mut logger = Options::new(path).build::<User>().await.unwrap();
logger.write(&User {id: 1, name: "fusio-log".to_string(), None}).await.unwrap();
```

## Build
### Build in Rust
```sh
cargo build
```

### Build in Wasm

Build with [wasm-pack](https://github.com/rustwasm/wasm-pack)

```sh
wasm-pack build --no-default-features --features web,bytes
```