1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
use crate::errors::*; use crate::engine::ctx::State; use crate::engine::structs::LuaList; use crate::hlua::{self, AnyLuaValue}; use regex::{Regex, Captures}; use std::sync::Arc; fn capture_to_lua(caps: &Captures) -> AnyLuaValue { let mut i = 0; let mut list = LuaList::new(); while let Some(cap) = caps.get(i) { list.push_str(cap.as_str()); i += 1; } list.into() } pub fn regex_find(lua: &mut hlua::Lua, state: Arc<dyn State>) { lua.set("regex_find", hlua::function2(move |regex: String, data: String| -> Result<AnyLuaValue> { let re = Regex::new(®ex) .map_err(|err| state.set_error(Error::from(err)))?; match re.captures(&data) { Some(caps) => Ok(capture_to_lua(&caps)), None => Ok(AnyLuaValue::LuaNil), } })) } pub fn regex_find_all(lua: &mut hlua::Lua, state: Arc<dyn State>) { lua.set("regex_find_all", hlua::function2(move |regex: String, data: String| -> Result<Vec<AnyLuaValue>> { let re = Regex::new(®ex) .map_err(|err| state.set_error(Error::from(err)))?; let list = re.captures_iter(&data) .map(|x| capture_to_lua(&x)) .collect(); Ok(list) })) } #[cfg(test)] mod tests { use crate::engine::ctx::Script; #[test] fn verify_find() { let script = Script::load_unchecked(r#" function run() m = regex_find(".(.)", "abcdef") if m == nil then return 'No captures' end if m[1] ~= 'ab' then return 'Incorrect result in m[1]' end if m[2] ~= 'b' then return 'Incorrect result in m[2]' end end "#).expect("Failed to load script"); script.test().expect("Script failed"); } #[test] fn verify_find_all() { let script = Script::load_unchecked(r#" function run() m = regex_find_all(".(.)", "abcdef") if m[1][1] ~= 'ab' then return 'Incorrect result in m[1][1]' end if m[1][2] ~= 'b' then return 'Incorrect result in m[1][2]' end if m[2][1] ~= 'cd' then return 'Incorrect result in m[2][1]' end if m[2][2] ~= 'd' then return 'Incorrect result in m[2][2]' end if m[3][1] ~= 'ef' then return 'Incorrect result in m[3][1]' end if m[3][2] ~= 'f' then return 'Incorrect result in m[3][2]' end end "#).expect("Failed to load script"); script.test().expect("Script failed"); } }