2 releases

0.1.1 May 7, 2021
0.1.0 May 6, 2021

#2284 in Data structures

MIT license

11KB
156 lines

afmt

Simple rust library for parsing basic data structures from strings.

Usage

You can specify string formats to any strucute, via the use of the fmt macro, in which you can specify a chain of string literals and struct member names, to represent the format of a structure.

#[fmt("value: " v "--" f)]
struct Foo {
    v: u32,
    r: f64,
}

let f: Foo = "value: 65--3.14".parse()?;

Limitations

Consider we want to parse strings similar to

some text here 364

into a struct with a String first part and a u32 second part.

If we tried parsing it as the following format attribute

#[fmt(msg v)]
struct Foo {
    msg: String,
    v: u32,
}

the result would be ambiguous, multiple interpretations could be

Foo {
    msg: "some text here ",
    v: 364,
}
Foo {
    msg: "some text here 3",
    v: 64,
}
Foo {
    msg: "some text here 36",
    v: 4,
}
            ...

this means that we must specify some literal delimiter between every pair of capture variables. Literal delimiters are parsed in a way that the first match splits the string, so a delimiter of " " would result in the two parts beign "some" and "text here 364", which is not ideal.

For this reason, you should consider which strings you can easily parse, by considering special delimiters, i.e. delimiters should not appear in data you want to capture.

Examples

#[macro_use] extern crate afmt;
#[fmt("value :" v)]
struct Foo {
    v: u32,
}

#[test]
fn it_works() {
    let f: Foo = "value: 65".parse().unwrap();
    assert_eq!(f.v, 65);
}
#[fmt("x[" x "] y[" y "]")]
struct Point {
    x: u32,
    y: u32,
}

#[test]
fn it_works() {
    let p: Point = "x[65] y[39]".parse().unwrap();
    assert_eq!(p.x, 65);
    assert_eq!(p.y, 39);
}
#[fmt("INFO: " msg)]
struct Bar {
    msg: String,
}

#[test]
fn it_works() {
    let b: Result<Bar,_> = "WARN: this is a warning".parse();
    assert!(b.is_err());
}

Dependencies

~2MB
~50K SLoC