From abe7217a58d560870d6693cab0396c1ed15c669b Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Sat, 20 Apr 2024 23:19:21 +0200 Subject: [PATCH] Add full type definitions for new regex builtin --- src/lune/builtins/regex/captures.rs | 4 +- src/lune/builtins/regex/matches.rs | 2 - types/regex.luau | 218 ++++++++++++++++++++++++++++ 3 files changed, 220 insertions(+), 4 deletions(-) create mode 100644 types/regex.luau diff --git a/src/lune/builtins/regex/captures.rs b/src/lune/builtins/regex/captures.rs index a1283e9..412370d 100644 --- a/src/lune/builtins/regex/captures.rs +++ b/src/lune/builtins/regex/captures.rs @@ -59,10 +59,10 @@ impl LuaCaptures { impl LuaUserData for LuaCaptures { fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { - methods.add_method("get", |_, this, n: usize| { + methods.add_method("get", |_, this, index: usize| { Ok(this .captures() - .get(n) + .get(index) .map(|m| LuaMatch::new(this.text(), m))) }); diff --git a/src/lune/builtins/regex/matches.rs b/src/lune/builtins/regex/matches.rs index d3b1fa9..42984a5 100644 --- a/src/lune/builtins/regex/matches.rs +++ b/src/lune/builtins/regex/matches.rs @@ -43,8 +43,6 @@ impl LuaUserData for LuaMatch { } fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { - methods.add_method("isEmpty", |_, this, ()| Ok(this.range().is_empty())); - methods.add_meta_method(LuaMetaMethod::Type, |_, _, ()| Ok("RegexMatch")); methods.add_meta_method(LuaMetaMethod::Len, |_, this, ()| Ok(this.range().len())); methods.add_meta_method(LuaMetaMethod::ToString, |_, this, ()| { diff --git a/types/regex.luau b/types/regex.luau new file mode 100644 index 0000000..e148c73 --- /dev/null +++ b/types/regex.luau @@ -0,0 +1,218 @@ +--[=[ + @class RegexMatch + + A match from a regular expression. + + Contains the following values: + + - `start` -- The start index of the match in the original string. + - `finish` -- The end index of the match in the original string. + - `text` -- The text that was matched. + - `len` -- The length of the text that was matched. +]=] +local RegexMatch = { + start = 0, + finish = 0, + text = "", + len = 0, +} + +type RegexMatch = typeof(RegexMatch) + +--[=[ + @class RegexCaptures + + Captures from a regular expression. +]=] +local RegexCaptures = {} + +--[=[ + @within RegexCaptures + @tag Method + + Returns the match at the given index, if one exists. + + @param index -- The index of the match to get + @return RegexMatch -- The match, if one exists +]=] +function RegexCaptures.get(self: RegexCaptures, index: number): RegexMatch? + return nil :: any +end + +--[=[ + @within RegexCaptures + @tag Method + + Returns the match for the given named match group, if one exists. + + @param group -- The name of the group to get + @return RegexMatch -- The match, if one exists +]=] +function RegexCaptures.group(self: RegexCaptures, group: string): RegexMatch? + return nil :: any +end + +--[=[ + @within RegexCaptures + @tag Method + + Formats the captures using the given format string. + + ### Example usage + + ```lua + local regex = require("@lune/regex") + + local re = regex.new("(?[0-9]{2})-(?[0-9]{2})-(?[0-9]{4})") + + local caps = re:captures("On 14-03-2010, I became a Tenneessee lamb."); + assert(caps ~= nil, "Example pattern should match example text") + + local formatted = caps:format("year=$year, month=$month, day=$day") + print(formatted) -- "year=2010, month=03, day=14" + ``` + + @param format -- The format string to use + @return string -- The formatted string +]=] +function RegexCaptures.format(self: RegexCaptures, format: string): string + return nil :: any +end + +export type RegexCaptures = typeof(RegexCaptures) + +local Regex = {} + +--[=[ + @within Regex + @tag Method + + Check if the given text matches the regular expression. + + This method may be slightly more efficient than calling `find` + if you only need to know if the text matches the pattern. + + @param text -- The text to search + @return boolean -- Whether the text matches the pattern +]=] +function Regex.isMatch(self: Regex, text: string): boolean + return nil :: any +end + +--[=[ + @within Regex + @tag Method + + Finds the first match in the given text. + + Returns `nil` if no match was found. + + @param text -- The text to search + @return RegexMatch? -- The match object +]=] +function Regex.find(self: Regex, text: string): RegexMatch? + return nil :: any +end + +--[=[ + @within Regex + @tag Method + + Finds all matches in the given text as a `RegexCaptures` object. + + Returns `nil` if no matches are found. + + @param text -- The text to search + @return RegexCaptures? -- The captures object +]=] +function Regex.captures(self: Regex, text: string): RegexCaptures? + return nil :: any +end + +--[=[ + @within Regex + @tag Method + + Splits the given text using the regular expression. + + @param text -- The text to split + @return { string } -- The split text +]=] +function Regex.split(self: Regex, text: string): { string } + return nil :: any +end + +--[=[ + @within Regex + @tag Method + + Replaces the first match in the given text with the given replacer string. + + @param haystack -- The text to search + @param replacer -- The string to replace matches with + @return string -- The text with the first match replaced +]=] +function Regex.replace(self: Regex, haystack: string, replacer: string): string + return nil :: any +end + +--[=[ + @within Regex + @tag Method + + Replaces all matches in the given text with the given replacer string. + + @param haystack -- The text to search + @param replacer -- The string to replace matches with + @return string -- The text with all matches replaced +]=] +function Regex.replaceAll(self: Regex, haystack: string, replacer: string): string + return nil :: any +end + +export type Regex = typeof(Regex) + +--[=[ + @class Regex + + Built-in library for regular expressions + + ### Example usage + + ```lua + local Regex = require("@lune/regex") + + local re = Regex.new("hello") + + if re:isMatch("hello, world!") then + print("Matched!") + end + + local caps = re:captures("hello, world! hello, again!") + + print(#caps) -- 2 + print(caps:get(1)) -- "hello" + print(caps:get(2)) -- "hello" + print(caps:get(3)) -- nil + ``` +]=] +local regex = {} + +--[=[ + @within Regex + @tag Constructor + + Creates a new `Regex` from a given string pattern. + + ### Errors + + This constructor throws an error if the given pattern is invalid. + + @param pattern -- The string pattern to use + @return Regex -- The new Regex object +]=] +function regex.new(pattern: string): Regex + return nil :: any +end + +return regex