sing_rs 0.1.3

Macros for generating STDIN/STDOUT interfaces to trait objects.
Documentation
# Sing

**S**td

**I**/o

**N**egotiator

**G**enerator

[![Crates.io](https://img.shields.io/crates/v/sing_rs)](https://crates.io/crates/sing_rs)
[![License](https://img.shields.io/crates/l/sing_rs)](https://www.gnu.org/licenses/agpl-3.0.html)

## What is sing?

This crate is meant to create interfaces between traits in Rust libraries and the command line.
It does this by providing two macros: 

- `sing_add_trait`, which acts as an attribute to a trait implementation and gathers the method signatures that are used by `sing_loop!`.
- `sing_loop!`, which takes a trait object and serialization/deserialization functions as well as some optional parameters. It generates a loop parsing function calls coming from STDIN (or any other `BufRead` stream), evaluating them by calling the appropriate method on the object and returning them on STDOUT (or any other `Write` stream).

## Usage example

```rust
use serde::{Serialize, Deserialize};
use sing_rs::{sing_add_trait, sing_loop};

trait FruitTree {
         fn shake(&self, shakes: u32) -> Vec<Fruit>;
}

#[derive(Debug, Serialize, Deserialize)]
struct Fruit {
         fruit_type: String,
}

struct BananaTree;

#[sing_add_trait()]
impl FruitTree for BananaTree {
         fn shake(&self, shakes: u32) -> Vec<Fruit>{
                  let mut out = vec!();

                  for _ in 0..shakes {
                                out.push(Fruit{fruit_type: String::from("Banana")});
                  }
                  
                  out
         }
}

fn main() {
         let tree = BananaTree {};
         
    sing_loop!(tree, [different, ron::to_string, ron::from_str],);
}
```

## Negotiator? Really?

Yes, it's somewhat far-fetched, but I really wanted to be able to sing and [clap](https://github.com/clap-rs/clap) in my rusty command-line projects.

## Why the name?

See above.