///|
/// A regex pattern used for matching parameter types in cucumber expressions.
pub(all) struct RegexPattern {
priv value : String
fn new(value : String) -> RegexPattern
} derive(Show, Eq)
///|
fn RegexPattern::new(value : String) -> RegexPattern {
{ value, }
}
///|
pub fn RegexPattern::to_string(self : RegexPattern) -> String {
self.value
}
///|
/// Parameter types supported by cucumber expressions.
pub(all) enum ParamType {
Int
Float
String_
Word
Anonymous
Double_
Long
Byte
Short
BigDecimal
BigInteger
Custom(String)
} derive(Show, Eq, ToJson, FromJson)
///|
/// A registered parameter type entry with name, type, regex patterns, and transformer.
pub(all) struct ParamTypeEntry {
name : String
type_ : ParamType
patterns : Array[RegexPattern]
transformer : Transformer
}
///|
impl Show for ParamTypeEntry with output(self, logger) {
logger.write_string("ParamTypeEntry { name: \{self.name}, type_: \{self.type_}, patterns: \{self.patterns} }")
}
///|
impl Eq for ParamTypeEntry with equal(self, other) -> Bool {
self.name == other.name && self.type_ == other.type_ && self.patterns == other.patterns
}
///|
/// Registry mapping parameter type names to their regex patterns.
pub(all) struct ParamTypeRegistry {
priv entries : Array[ParamTypeEntry]
}
///|
pub fn ParamTypeRegistry::new() -> ParamTypeRegistry {
{ entries: [] }
}
///|
/// Create a registry with the 11 built-in parameter types pre-registered.
pub fn ParamTypeRegistry::default() -> ParamTypeRegistry {
let reg = ParamTypeRegistry::new()
// Integer types (all share the same regex patterns)
let int_patterns = [
RegexPattern("(?:-?\\d+)"),
RegexPattern("(?:\\d+)"),
]
reg.register("int", ParamType::Int, int_patterns,
transformer=Transformer::new(fn(groups) raise { IntVal(@strconv.parse_int(groups[0])) }),
)
reg.register("long", ParamType::Long, int_patterns,
transformer=Transformer::new(fn(groups) raise { LongVal(@strconv.parse_int64(groups[0])) }),
)
reg.register("byte", ParamType::Byte, int_patterns,
transformer=Transformer::new(fn(groups) raise { ByteVal(@strconv.parse_int(groups[0]).to_byte()) }),
)
reg.register("short", ParamType::Short, int_patterns,
transformer=Transformer::new(fn(groups) raise { ShortVal(@strconv.parse_int(groups[0])) }),
)
reg.register("biginteger", ParamType::BigInteger, int_patterns,
transformer=Transformer::new(fn(groups) { BigIntegerVal(BigInt::from_string(groups[0])) }),
)
// Float types (all share the same regex pattern)
let float_patterns = [
RegexPattern("(?:[+-]?(?:\\d+|\\d+\\.\\d*|\\d*\\.\\d+)(?:[eE][+-]?\\d+)?)"),
]
reg.register("float", ParamType::Float, float_patterns,
transformer=Transformer::new(fn(groups) raise { FloatVal(@strconv.parse_double(groups[0])) }),
)
reg.register("double", ParamType::Double_, float_patterns,
transformer=Transformer::new(fn(groups) raise { DoubleVal(@strconv.parse_double(groups[0])) }),
)
reg.register("bigdecimal", ParamType::BigDecimal, float_patterns,
transformer=Transformer::new(fn(groups) raise {
match @decimal.Decimal::from_string(groups[0]) {
Some(d) => BigDecimalVal(d)
None => raise Failure::Failure("Invalid bigdecimal: " + groups[0])
}
}),
)
// String and word (identity transformers)
reg.register("string", ParamType::String_, [
RegexPattern("\"([^\"\\\\]*(\\\\.[^\"\\\\]*)*)\""),
RegexPattern("'([^'\\\\]*(\\\\.[^'\\\\]*)*)'"),
],
transformer=Transformer::new(fn(groups) { StringVal(groups[0]) }),
)
reg.register("word", ParamType::Word, [RegexPattern("[^\\s]+")],
transformer=Transformer::new(fn(groups) { WordVal(groups[0]) }),
)
reg.register("", ParamType::Anonymous, [RegexPattern(".*")],
transformer=Transformer::new(fn(groups) { AnonymousVal(groups[0]) }),
)
reg
}
///|
pub fn ParamTypeRegistry::register(
self : ParamTypeRegistry,
name : String,
type_ : ParamType,
patterns : Array[RegexPattern],
transformer~ : Transformer = Transformer::new(fn(groups) { ParamValue::CustomVal(@any.of(groups[0])) }),
) -> Unit {
self.entries.push({ name, type_, patterns, transformer })
}
///|
pub fn ParamTypeRegistry::get(
self : ParamTypeRegistry,
name : String,
) -> ParamTypeEntry? {
for entry in self.entries {
if entry.name == name {
return Some(entry)
}
}
None
}
///|
/// Read-only view of all registered parameter type entries.
pub fn ParamTypeRegistry::entries_view(
self : ParamTypeRegistry,
) -> ArrayView[ParamTypeEntry] {
self.entries[:]
}