refactor(varcon): Reduce boilerplate

This commit is contained in:
Ed Page 2024-08-23 10:01:39 -05:00
parent 0068450bf1
commit 62aab867ab

View file

@ -1,7 +1,13 @@
use winnow::ascii::space1;
use winnow::combinator::alt;
use winnow::combinator::cut_err; use winnow::combinator::cut_err;
use winnow::combinator::delimited; use winnow::combinator::delimited;
use winnow::combinator::opt;
use winnow::combinator::preceded;
use winnow::combinator::terminated;
use winnow::combinator::trace; use winnow::combinator::trace;
use winnow::prelude::*; use winnow::prelude::*;
use winnow::token::one_of;
use crate::{Category, Cluster, Entry, Pos, Tag, Type, Variant}; use crate::{Category, Cluster, Entry, Pos, Tag, Type, Variant};
@ -548,18 +554,15 @@ impl Cluster {
winnow::ascii::till_line_ending, winnow::ascii::till_line_ending,
winnow::ascii::line_ending, winnow::ascii::line_ending,
); );
let note = winnow::combinator::preceded( let note = preceded(
("##", winnow::ascii::space0), ("##", winnow::ascii::space0),
winnow::combinator::terminated( terminated(winnow::ascii::till_line_ending, winnow::ascii::line_ending),
winnow::ascii::till_line_ending,
winnow::ascii::line_ending,
),
); );
let mut cluster = ( let mut cluster = (
winnow::combinator::opt(header), opt(header),
winnow::combinator::repeat( winnow::combinator::repeat(
1.., 1..,
winnow::combinator::terminated(Entry::parse_, winnow::ascii::line_ending), terminated(Entry::parse_, winnow::ascii::line_ending),
), ),
winnow::combinator::repeat(0.., note), winnow::combinator::repeat(0.., note),
); );
@ -962,16 +965,11 @@ impl Entry {
winnow::combinator::separated(1.., Variant::parse_, var_sep).parse_next(input)?; winnow::combinator::separated(1.., Variant::parse_, var_sep).parse_next(input)?;
let desc_sep = (winnow::ascii::space0, '|'); let desc_sep = (winnow::ascii::space0, '|');
let description = let description = opt((desc_sep, Self::parse_description)).parse_next(input)?;
winnow::combinator::opt((desc_sep, Self::parse_description)).parse_next(input)?;
let comment_sep = (winnow::ascii::space0, '#'); let comment_sep = (winnow::ascii::space0, '#');
let comment = winnow::combinator::opt(( let comment =
comment_sep, opt((comment_sep, space1, winnow::ascii::till_line_ending)).parse_next(input)?;
winnow::ascii::space1,
winnow::ascii::till_line_ending,
))
.parse_next(input)?;
let mut e = match description { let mut e = match description {
Some((_, description)) => description, Some((_, description)) => description,
@ -993,19 +991,13 @@ impl Entry {
fn parse_description(input: &mut &str) -> PResult<Self, ()> { fn parse_description(input: &mut &str) -> PResult<Self, ()> {
trace("description", move |input: &mut &str| { trace("description", move |input: &mut &str| {
let _ = winnow::combinator::opt((winnow::ascii::space1, "<abbr>")).parse_next(input)?; let _ = opt((space1, "<abbr>")).parse_next(input)?;
let _ = winnow::combinator::opt((winnow::ascii::space1, "<pl>")).parse_next(input)?; let _ = opt((space1, "<pl>")).parse_next(input)?;
let pos = winnow::combinator::opt(( let pos = opt((space1, delimited('<', cut_err(Pos::parse_), cut_err('>'))))
winnow::ascii::space1, .parse_next(input)?;
delimited('<', cut_err(Pos::parse_), cut_err('>')), let archaic = opt((space1, archaic)).parse_next(input)?;
)) let note = opt((space1, NOTE_PREFIX)).parse_next(input)?;
.parse_next(input)?; let description = opt((space1, description)).parse_next(input)?;
let archaic =
winnow::combinator::opt((winnow::ascii::space1, archaic)).parse_next(input)?;
let note =
winnow::combinator::opt((winnow::ascii::space1, NOTE_PREFIX)).parse_next(input)?;
let description =
winnow::combinator::opt((winnow::ascii::space1, description)).parse_next(input)?;
let variants = Vec::new(); let variants = Vec::new();
let pos = pos.map(|(_, p)| p); let pos = pos.map(|(_, p)| p);
@ -1523,7 +1515,7 @@ impl Variant {
fn parse_(input: &mut &str) -> PResult<Self, ()> { fn parse_(input: &mut &str) -> PResult<Self, ()> {
trace("variant", move |input: &mut &str| { trace("variant", move |input: &mut &str| {
let types = winnow::combinator::separated(1.., Type::parse_, winnow::ascii::space1); let types = winnow::combinator::separated(1.., Type::parse_, space1);
let sep = (":", winnow::ascii::space0); let sep = (":", winnow::ascii::space0);
let (types, word) = let (types, word) =
winnow::combinator::separated_pair(types, sep, word).parse_next(input)?; winnow::combinator::separated_pair(types, sep, word).parse_next(input)?;
@ -1650,8 +1642,8 @@ impl Type {
fn parse_(input: &mut &str) -> PResult<Type, ()> { fn parse_(input: &mut &str) -> PResult<Type, ()> {
trace("type", move |input: &mut &str| { trace("type", move |input: &mut &str| {
let category = Category::parse_(input)?; let category = Category::parse_(input)?;
let tag = winnow::combinator::opt(Tag::parse_).parse_next(input)?; let tag = opt(Tag::parse_).parse_next(input)?;
let num = winnow::combinator::opt(winnow::ascii::digit1).parse_next(input)?; let num = opt(winnow::ascii::digit1).parse_next(input)?;
let num = num.map(|s| s.parse().expect("parser ensured it's a number")); let num = num.map(|s| s.parse().expect("parser ensured it's a number"));
let t = Type { category, tag, num }; let t = Type { category, tag, num };
Ok(t) Ok(t)
@ -1765,7 +1757,7 @@ impl Category {
fn parse_(input: &mut &str) -> PResult<Self, ()> { fn parse_(input: &mut &str) -> PResult<Self, ()> {
trace("category", move |input: &mut &str| { trace("category", move |input: &mut &str| {
let symbols = winnow::token::one_of(['A', 'B', 'Z', 'C', 'D', '_']); let symbols = one_of(['A', 'B', 'Z', 'C', 'D', '_']);
symbols symbols
.map(|c| match c { .map(|c| match c {
'A' => Category::American, 'A' => Category::American,
@ -1824,7 +1816,7 @@ impl Tag {
fn parse_(input: &mut &str) -> PResult<Self, ()> { fn parse_(input: &mut &str) -> PResult<Self, ()> {
trace("tag", move |input: &mut &str| { trace("tag", move |input: &mut &str| {
let symbols = winnow::token::one_of(['.', 'v', 'V', '-', 'x']); let symbols = one_of(['.', 'v', 'V', '-', 'x']);
symbols symbols
.map(|c| match c { .map(|c| match c {
'.' => Tag::Eq, '.' => Tag::Eq,
@ -1882,7 +1874,7 @@ impl Pos {
fn parse_(input: &mut &str) -> PResult<Self, ()> { fn parse_(input: &mut &str) -> PResult<Self, ()> {
trace("pos", move |input: &mut &str| { trace("pos", move |input: &mut &str| {
winnow::combinator::alt(( alt((
"N".value(Pos::Noun), "N".value(Pos::Noun),
"V".value(Pos::Verb), "V".value(Pos::Verb),
"Adj".value(Pos::Adjective), "Adj".value(Pos::Adjective),