From Nested Tuple
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 = { git = "https://github.com/MasterTemple/from_nested_tuple" }
Option B: Run cargo command
cargo add --git "https://github.com/MasterTemple/from_nested_tuple"