reformation 0.3.0

Parsing via regular expressions
Documentation
[![Build Status](https://travis-ci.org/hukumka/reformation.svg?branch=master)](https://travis-ci.org/hukumka/reformation)

# reformation

 Parsing via regular expressions using format syntax

 Deriving trait `Reformation` will also implement
 trait `FromStr`, with `Err=Box<Error>`

 Derive will require attribute reformation to specify format string,
 which will be treated as format string -> regular expression string

 Types implementing `Reformation` by default:

 + signed integers: `i8` `i16` `i32` `i64` `i128` `isize`
 + unsigned integers: `u8` `u16` `u32` `u64` `u128` `usize`
 + floats: `f32` `f64`
 + `String`
 + `char`
 
 It can be used to parse:
 

## Structs

 ```rust
 use reformation::Reformation;

 #[derive(Reformation, Debug)]
 #[reformation(r"{year}-{month}-{day} {hour}:{minute}")]
 struct Date{
     year: u16,
     month: u8,
     day: u8,
     hour: u8,
     minute: u8,
 }

 fn main(){
     let date: Date = "2018-12-22 20:23".parse().unwrap();

     assert_eq!(date.year, 2018);
     assert_eq!(date.month, 12);
     assert_eq!(date.day, 22);
     assert_eq!(date.hour, 20);
     assert_eq!(date.minute, 23);
 }
 ```

## Tuple Structs


```rust
use reformation::Reformation;

#[derive(Reformation)]

#[reformation(r"{} -> {}")]

struct Predicate(Empty, char);

#[derive(Reformation, Debug, PartialEq)]

#[reformation(r"Empty")]

struct Empty;

fn main(){
    let p: Predicate = "Empty -> X".parse().unwrap();
    assert_eq!(p.0, Empty);
    assert_eq!(p.1, 'X');
}
```

## Enums

Current enum supports only following pattern: `r"(variant1|variant2|variant_with_value\({}\)|other_variant_with_value{})"`
```rust
use reformation::Reformation;

#[derive(Reformation, Eq, PartialEq, Debug)]

#[reformation(r"(Queen\({}\)|Worker\({}\)|Warrior)")]

enum Ant{
    Queen(String),
    Worker(i32),
    Warrior
}

 fn main(){
     let queen: Ant = "Queen(We are swarm)".parse().unwrap();
     assert_eq!(queen, Ant::Queen("We are swarm".to_string()));

     let worker: Ant = "Worker(900000)".parse().unwrap();
     assert_eq!(worker, Ant::Worker(900000));

     let warrior: Ant = "Warrior".parse().unwrap();
     assert_eq!(warrior, Ant::Warrior);
 }
 ```

## Modes


There are some modes, that can be applied to regular expression.

Order, in which modes are specified does not matter.

### no_regex


Makes format string behave as regular string (in contrast with being regular expression),
by escaping all special regex characters.

```rust
use reformation::Reformation;

#[derive(Reformation, Debug)]

#[reformation("Vec{{{x}, {y}}}", no_regex=true)]

struct Vec{
    x: i32,
    y: i32,
}

fn main(){
    let v: Vec = "Vec{-1, 1}".parse().unwrap();
    assert_eq!(v.x, -1);
    assert_eq!(v.y, 1);
}
```

### slack


Allow arbitrary number of spaces after separators: ',', ';', ':'. For separator to be recognized
as slack, it must be followed by at least one space in format string.

```rust
use reformation::Reformation;

#[derive(Reformation, Debug)]

#[reformation(r"Vec\{{{x}, {y}\}}", slack=true)]

struct Vec{
    x: i32,
    y: i32,
}

fn main(){
    let v: Vec = "Vec{-1,1}".parse().unwrap();
    assert_eq!(v.x, -1);
    assert_eq!(v.y, 1);

    let r: Vec = "Vec{15,   2}".parse().unwrap();
    assert_eq!(r.x, 15);
    assert_eq!(r.y, 2);
}
```

Combination of no_regex and slack behaves as expected:

```rust
use reformation::Reformation;

#[derive(Reformation, Debug)]

#[reformation(r"Vec({x}; {y})", slack=true, no_regex=true)]

struct Vec{
    x: i32,
    y: i32,
}

fn main(){
    let v: Vec = "Vec(-1;1)".parse().unwrap();
    assert_eq!(v.x, -1);
    assert_eq!(v.y, 1);

    let r: Vec = "Vec(15;   2)".parse().unwrap();
    assert_eq!(r.x, 15);
    assert_eq!(r.y, 2);
}
```