from_nested_tuple 0.1.2

Create structs from left-nested tuples (meant to complement chumsky)
Documentation

From Nested Tuple

Latest Version Repo

Create structs from left-nested tuples


This is created to easily unnest tuples (from chained .then statements) in chumsky.

Go from

some().nested().parser().map(|(((child1, child2), child3), child4)| {
    Parent {
        child1,
        child2,
        child3,
        child4,
    }
})

to

some().nested().parser().from_tuple()

Usage

Import

use from_nested_tuple::FromTuple;

derive (if using on a struct, it is already implemented for built-in tuples)

#[derive(FromTuple)]
struct WithNamedFields {
    a: char,
    b: char,
    c: char,
}

call .from_tuple()

impl WithNamedFields {
    fn parser<'a>() -> impl Parser<'a, &'a str, Self> {
        any().then(any()).then(any()).from_tuple()
    }
}

Exports

  • FromTuple: for the derive macro (#[derive(FromTuple)]) and trait that extends the parser (.from_tuple())
  • FromNestedTuple: the trait derived by FromTuple (automatically imported for tuples 2 to 64)

Note: calling .from_tuple() is the same as .map(FromNestedTuple::from_nested_tuple), but requires no extra imports

Examples

See: examples/named.rs

use chumsky::prelude::*;
use from_nested_tuple::FromTuple;

#[derive(Debug, PartialEq, Eq, FromTuple)]
struct WithNamedFields {
    a: char,
    b: char,
    c: char,
}

impl WithNamedFields {
    fn parser<'a>() -> impl Parser<'a, &'a str, Self> {
        any().then(any()).then(any()).from_tuple()
    }
}

fn main() {
    assert_eq!(
        WithNamedFields::parser().parse("123").unwrap(),
        WithNamedFields {
            a: '1',
            b: '2',
            c: '3'
        }
    );
}

which derives

impl from_nested_tuple::FromNestedTuple for WithNamedFields {
    type Tuple = ((char, char), char);
    fn from_nested_tuple(tuple: Self::Tuple) -> Self {
        let ((a, b), c) = tuple;
        Self { a, b, c }
    }
}

See: examples/unnamed.rs

use chumsky::prelude::*;
use from_nested_tuple::FromTuple;

#[derive(Debug, PartialEq, Eq, FromTuple)]
struct WithUnnamedFields(char, char, char);

impl WithUnnamedFields {
    fn parser<'a>() -> impl Parser<'a, &'a str, Self> {
        any().then(any()).then(any()).from_tuple()
    }
}

fn main() {
    assert_eq!(
        WithUnnamedFields::parser().parse("abc").unwrap(),
        WithUnnamedFields('a', 'b', 'c')
    );
}

which derives

impl from_nested_tuple::FromNestedTuple for WithUnnamedFields {
    type Tuple = ((char, char), char);
    fn from_nested_tuple(tuple: Self::Tuple) -> Self {
        let ((field0, field1), field2) = tuple;
        Self(field0, field1, field2)
    }
}

See: examples/tuples.rs

use chumsky::prelude::*;
use from_nested_tuple::FromTuple;

fn parser<'a>() -> impl Parser<'a, &'a str, (char, char, char)> {
    any().then(any()).then(any()).from_tuple()
}

fn main() {
    assert_eq!(parser().parse("abc").unwrap(), ('a', 'b', 'c'))
}

Installation

Option A: Modify Cargo.toml

from_nested_tuple = "0.1.2"

Option B: Run cargo command

cargo add from_nested_tuple