# rust-racs
[](https://crates.io/crates/racs)
**rust-racs** is the rust client library for [RACS](https://github.com/racslabs/racs).
## Installation
Run the following Cargo command in your project directory:
```
cargo add racs
```
Or add the following line to your Cargo.toml:
```
racs = "0.1.2"
```
## Basic Operations
To open a connection, simply create a client using ``open``.
```rust
use racs::Client;
let client = Client::open("127.0.0.1:6381").unwrap();
```
The ``open`` function creates a client with a default connection pool size of 3.
To specify the connection pool size, use ``open_with_pool_size``.
```rust
use racs::Client;
let client = Client::open_with_pool_size("127.0.0.1:6381", 5).unrwap();
```
### Streaming Audio
The ``pipeline`` function is used to chain together multiple RACS commands and execute them sequentially.
In the below example, a new audio stream is created. Then PCM data is chunked into frames
and streamed to the RACS server.
```rust
use racs::Client;
// Connect to the RACS server
let mut client = Client::open("127.0.0.1:6381").unwrap();
// Create a new audio stream using pipeline
client.pipeline()
.create("vocals", 44100, 2, 16) // stream-id, sample-rate, channels, bit-depth
.execute()
.unwrap();
// Prepare PCM samples (interleaved L/R, 16- or 24-bit integers)
let samples: Vec<i32> = /* your PCM audio data */
// Stream audio data to the server
client.stream("vocals")
.chunk_size(1024 * 32) // 32 KB
.batch_size(50)
.compression(true)
.compression_level(8) // ZSTD levels: 0-8
.execute(&samples)
.unwrap();
```
If `chunk_size`, `batch_size`, `compression` and `compression_level` are not provided, the default values will be used.
```rust
// Stream audio data to the server
client.stream("vocals").execute(&samples).unwrap();
```
Stream ids stored in RACS can be queried using the ``list`` command. ``list`` takes a glob pattern and returns a list of streams ids matching the pattern.
```rust
use racs::Client;
let client = Client::open("127.0.0.1:6381").unwrap();
let result = client.pipeline()
.list("*")
.execute()
.unwrap();
// List([String("vocals")])
println!("{:?}", result);
```
### Extracting Audio
The below example extracts a 30-second PCM audio segment using the ``range`` command. It then encodes the data to MP3 and writes the resulting bytes to a file.
```rust
use racs::Client;
use racs::Type;
use std::fs::File;
use std::io::Write;
// Connect to the RACS server
let client = Client::open("127.0.0.1:6381").unwrap();
// Extract PCM data
// Encode to MP3
let result = client.pipeline()
.range("vocals", 0.0, 30.0) // stream-id, start-time (seconds), duration (seconds)
.encode("audio/mp3") // mime-type
.execute()
.unwrap();
// Write to a file
if let Type::U8V(data) = result {
let mut file = File::create("vocals.mp3").unwrap();
file.write_all(&data).unwrap();
}
```
### Metadata
Stream metadata can be retrieved using the ``meta`` command. ``meta`` takes the stream id and metadata attribute as parameters.
```rust
use racs::Client;
use racs::Type;
// Connect to the RACS server
let client = Client::open("127.0.0.1:6381").unwrap();
// Get sample rate attribute for stream
let result = client
.pipeline()
.meta("vocals", "sample_rate")
.execute();
// Print the sample rate
if let Type::Int(sample_rate) = result.unwrap() {
// 44100
println!("{}", sample_rate);
}
```
``i64`` is returned for all metadata attributes. The supported attributes are:
| `channels` | Channel count of the audio stream. |
| `sample_rate` | Sample rate of the audio stream (Hz). |
| `bit_depth` | Bit depth of the audio stream. |
| `ref` | Reference timestamp (milliseconds UTC). |
| `size` | Size of uncompressed audio stream in bytes. |
### Raw Command Execution
To execute raw command strings, use the ``execute_command`` function.
```rust
use racs::Client;
use racs::Type;
let client = Client::open("127.0.0.1:6381").unwrap();
let result = client.execute_command("EVAL '(+ 1 2 3)'");
if let Type::Int(num) = result.unwrap() {
}
```
Refer to the documentation in [RACS](https://github.com/racslabs/racs) for the commands.
## Type Conversions
Below is a table of conversions for the ``Type`` enum between RACS and rust:
| `Type::Int` | `i64` |
| `Type::Float` | `f64` |
| `Type::Bool` | `bool` |
| `Type::String` | `String` |
| `Type::Error` | `Err` |
| `Type::Null` | N/A |
| `Type::U8V` | `Vec<u8>` |
| `Type::U16V` | `Vec<u16>` |
| `Type::S16V` | `Vec<i16>` |
| `Type::U32V` | `Vec<u32>` |
| `Type::S32V` | `Vec<i32>` |
| `Type::C64V` | `Vec<Complex32>` |
| `Type::List` | `Vec<Type>` |