use crate::base::{Element, Rec};
macro_rules! rpt {
($elmt:expr, $rep:expr) => {
format!("{}{}", $elmt.group(), $rep).into_rec()
};
}
macro_rules! num_rpt {
($elmt:expr, $count:expr) => {
format!("{}{{{}}}", $elmt.group(), $count).into_rec()
};
($elmt:expr, $min:expr, $max:expr) => {
format!("{}{{{},{}}}", $elmt.group(), $min, $max).into_rec()
};
($elmt:expr, $min:expr, $max:expr, $lazy:expr) => {
format!("{}{{{},{}}}?", $elmt.group(), $min, $max).into_rec()
};
}
const NO_MAX: &str = "";
#[inline]
pub fn var<T: Element>(element: T) -> Rec {
rpt!(element, "*")
}
#[inline]
pub fn lazy_var<T: Element>(element: T) -> Rec {
rpt!(element, "*?")
}
#[inline]
pub fn some<T: Element>(element: T) -> Rec {
rpt!(element, "+")
}
#[inline]
pub fn lazy_some<T: Element>(element: T) -> Rec {
rpt!(element, "+?")
}
#[inline]
pub fn opt<T: Element>(element: T) -> Rec {
rpt!(element, "?")
}
#[inline]
pub fn lazy_opt<T: Element>(element: T) -> Rec {
rpt!(element, "??")
}
#[inline]
pub fn exact<T: Element>(quantity: usize, element: T) -> Rec {
num_rpt!(element, quantity)
}
#[inline]
pub fn min<T: Element>(quantity: usize, element: T) -> Rec {
num_rpt!(element, quantity, NO_MAX)
}
#[inline]
pub fn lazy_min<T: Element>(quantity: usize, element: T) -> Rec {
num_rpt!(element, quantity, NO_MAX, true)
}
#[inline]
pub fn btwn<T: Element>(min: usize, max: usize, element: T) -> Rec {
num_rpt!(element, min, max)
}
#[inline]
pub fn lazy_btwn<T: Element>(min: usize, max: usize, element: T) -> Rec {
num_rpt!(element, min, max, true)
}