1use bstr::ByteSlice;
2use config::{from_lua_value, get_or_create_sub_module};
3use kumo_template::TemplateDialect;
4use mlua::Lua;
5
6pub fn register(lua: &Lua) -> anyhow::Result<()> {
7 let string_mod = get_or_create_sub_module(lua, "string")?;
8
9 string_mod.set(
10 "replace",
11 lua.create_function(move |_, (s, from, to): (String, String, String)| {
12 Ok(s.replace(&from, &to))
13 })?,
14 )?;
15
16 string_mod.set(
17 "replacen",
18 lua.create_function(
19 move |_, (s, from, to, count): (String, String, String, usize)| {
20 Ok(s.replacen(&from, &to, count))
21 },
22 )?,
23 )?;
24
25 string_mod.set(
26 "rsplit",
27 lua.create_function(move |_, (s, pattern): (String, String)| {
28 Ok(s.rsplit(&pattern)
29 .map(|s| s.to_string())
30 .collect::<Vec<String>>())
31 })?,
32 )?;
33
34 string_mod.set(
35 "rsplitn",
36 lua.create_function(move |_, (s, limit, pattern): (String, usize, String)| {
37 Ok(s.rsplitn(limit, &pattern)
38 .map(|s| s.to_string())
39 .collect::<Vec<String>>())
40 })?,
41 )?;
42
43 string_mod.set(
44 "starts_with",
45 lua.create_function(move |_, (s, pattern): (mlua::String, mlua::String)| {
46 Ok(s.as_bytes().starts_with_str(pattern.as_bytes()))
47 })?,
48 )?;
49
50 string_mod.set(
51 "ends_with",
52 lua.create_function(move |_, (s, pattern): (mlua::String, mlua::String)| {
53 Ok(s.as_bytes().ends_with_str(pattern.as_bytes()))
54 })?,
55 )?;
56
57 string_mod.set(
58 "split",
59 lua.create_function(move |_, (s, pattern): (String, String)| {
60 Ok(s.split(&pattern)
61 .map(|s| s.to_string())
62 .collect::<Vec<String>>())
63 })?,
64 )?;
65
66 string_mod.set(
67 "splitn",
68 lua.create_function(move |_, (s, limit, pattern): (String, usize, String)| {
69 Ok(s.splitn(limit, &pattern)
70 .map(|s| s.to_string())
71 .collect::<Vec<String>>())
72 })?,
73 )?;
74
75 string_mod.set(
76 "split_whitespace",
77 lua.create_function(move |_, s: String| {
78 Ok(s.split_whitespace()
79 .map(|s| s.to_string())
80 .collect::<Vec<String>>())
81 })?,
82 )?;
83
84 string_mod.set(
85 "split_ascii_whitespace",
86 lua.create_function(move |_, s: String| {
87 Ok(s.split_ascii_whitespace()
88 .map(|s| s.to_string())
89 .collect::<Vec<String>>())
90 })?,
91 )?;
92
93 string_mod.set(
94 "trim",
95 lua.create_function(move |_, s: String| Ok(s.trim().to_string()))?,
96 )?;
97 string_mod.set(
98 "trim_end",
99 lua.create_function(move |_, s: String| Ok(s.trim_end().to_string()))?,
100 )?;
101 string_mod.set(
102 "trim_start",
103 lua.create_function(move |_, s: String| Ok(s.trim_start().to_string()))?,
104 )?;
105
106 string_mod.set(
107 "psl_domain",
108 lua.create_function(move |_, s: String| {
109 let n = psl_utils::normalize_domain(&s);
110 Ok(psl_utils::domain_str(&n).map(|s| s.to_string()))
111 })?,
112 )?;
113
114 string_mod.set(
115 "psl_suffix",
116 lua.create_function(move |_, s: String| {
117 let n = psl_utils::normalize_domain(&s);
118 Ok(psl_utils::suffix_str(&n).map(|s| s.to_string()))
119 })?,
120 )?;
121
122 string_mod.set(
123 "eval_template",
124 lua.create_function(
125 move |lua,
126 (name, template, context, opt_dialect): (
127 String,
128 String,
129 mlua::Value,
130 mlua::Value,
131 )| {
132 let dialect: Option<TemplateDialect> = from_lua_value(lua, opt_dialect)?;
133 let engine =
134 kumo_template::TemplateEngine::with_dialect(dialect.unwrap_or_default());
135 engine
136 .render(&name, &template, context)
137 .map_err(config::any_err)
138 },
139 )?,
140 )?;
141
142 string_mod.set(
143 "wrap",
144 lua.create_function(
145 move |lua, (text, soft, hard): (mlua::String, Option<usize>, Option<usize>)| {
146 let soft = soft.unwrap_or(75);
147 let hard = hard.unwrap_or(900);
148 let bytes = kumo_wrap::wrap_impl(&*text.as_bytes(), soft, hard);
149 lua.create_string(bytes.trim_end())
150 },
151 )?,
152 )?;
153
154 Ok(())
155}