From 761ab0a24fccb4c560367b583b608fbae5f31647 Mon Sep 17 00:00:00 2001 From: LoganDark Date: Thu, 12 May 2022 10:32:53 -0700 Subject: [PATCH] Implement `nom::sequence::Tuple` for `()` (Unit) --- src/sequence/mod.rs | 9 +++++++++ src/sequence/tests.rs | 9 ++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/sequence/mod.rs b/src/sequence/mod.rs index e09d413..735ab45 100644 --- a/src/sequence/mod.rs +++ b/src/sequence/mod.rs @@ -252,6 +252,15 @@ macro_rules! tuple_trait_inner( tuple_trait!(FnA A, FnB B, FnC C, FnD D, FnE E, FnF F, FnG G, FnH H, FnI I, FnJ J, FnK K, FnL L, FnM M, FnN N, FnO O, FnP P, FnQ Q, FnR R, FnS S, FnT T, FnU U); +// Special case: implement `Tuple` for `()`, the unit type. +// This can come up in macros which accept a variable number of arguments. +// Literally, `()` is an empty tuple, so it should simply parse nothing. +impl> Tuple for () { + fn parse(&mut self, input: I) -> IResult { + Ok((input, ())) + } +} + ///Applies a tuple of parsers one by one and returns their results as a tuple. ///There is a maximum of 21 parsers /// ```rust diff --git a/src/sequence/tests.rs b/src/sequence/tests.rs index 201579b..ea66260 100644 --- a/src/sequence/tests.rs +++ b/src/sequence/tests.rs @@ -1,6 +1,6 @@ use super::*; use crate::bytes::streaming::{tag, take}; -use crate::error::ErrorKind; +use crate::error::{ErrorKind, Error}; use crate::internal::{Err, IResult, Needed}; use crate::number::streaming::be_u16; @@ -272,3 +272,10 @@ fn tuple_test() { Err(Err::Error(error_position!(&b"jk"[..], ErrorKind::Tag))) ); } + +#[test] +fn unit_type() { + assert_eq!(tuple::<&'static str, (), Error<&'static str>, ()>(())("abxsbsh"), Ok(("abxsbsh", ()))); + assert_eq!(tuple::<&'static str, (), Error<&'static str>, ()>(())("sdfjakdsas"), Ok(("sdfjakdsas", ()))); + assert_eq!(tuple::<&'static str, (), Error<&'static str>, ()>(())(""), Ok(("", ()))); +}