1pub struct ModuleFn {
13 pub name: &'static str,
14 pub arity: usize,
15 pub optional: bool,
16 pub runtime_fn: &'static str,
17 pub hint: &'static str,
18}
19
20impl ModuleFn {
21 pub fn max_arity(&self) -> usize {
23 self.arity + self.optional as usize
24 }
25}
26
27pub struct Module {
30 pub name: &'static str,
31 pub funcs: &'static [ModuleFn],
32 pub consts: &'static [(&'static str, &'static str)],
33}
34
35impl Module {
36 pub fn func(&self, name: &str) -> Option<&'static ModuleFn> {
38 self.funcs.iter().find(|f| f.name == name)
39 }
40
41 pub fn const_expr(&self, name: &str) -> Option<&'static str> {
43 self.consts
44 .iter()
45 .find(|(n, _)| *n == name)
46 .map(|(_, expr)| *expr)
47 }
48
49 pub fn members(&self) -> String {
51 let mut names: Vec<&str> = self.funcs.iter().map(|f| f.name).collect();
52 names.extend(self.consts.iter().map(|(n, _)| *n));
53 names.join(", ")
54 }
55
56 pub fn first_member(&self) -> &'static str {
58 self.funcs
59 .first()
60 .map(|f| f.name)
61 .or_else(|| self.consts.first().map(|(n, _)| *n))
62 .unwrap_or("")
63 }
64}
65
66pub const PACK_ZOOM_RUNTIME_FN: &str = "pack_zoom";
71
72pub fn module(name: &str) -> Option<&'static Module> {
74 MODULES.iter().find(|m| m.name == name)
75}
76
77pub(crate) fn module_names() -> String {
79 MODULES
80 .iter()
81 .map(|m| m.name)
82 .collect::<Vec<_>>()
83 .join(", ")
84}
85
86pub const MODULES: &[Module] = &[
87 Module {
88 name: "nerd",
89 funcs: &[
90 ModuleFn {
91 name: "abs",
92 arity: 1,
93 optional: false,
94 runtime_fn: "nerd_abs",
95 hint: "nerd.abs(x)",
96 },
97 ModuleFn {
98 name: "sqrt",
99 arity: 1,
100 optional: false,
101 runtime_fn: "nerd_sqrt",
102 hint: "nerd.sqrt(x)",
103 },
104 ModuleFn {
105 name: "floor",
106 arity: 1,
107 optional: false,
108 runtime_fn: "nerd_floor",
109 hint: "nerd.floor(x)",
110 },
111 ModuleFn {
112 name: "ceil",
113 arity: 1,
114 optional: false,
115 runtime_fn: "nerd_ceil",
116 hint: "nerd.ceil(x)",
117 },
118 ModuleFn {
119 name: "round",
120 arity: 1,
121 optional: false,
122 runtime_fn: "nerd_round",
123 hint: "nerd.round(x)",
124 },
125 ModuleFn {
126 name: "min",
127 arity: 2,
128 optional: false,
129 runtime_fn: "nerd_min",
130 hint: "nerd.min(a, b)",
131 },
132 ModuleFn {
133 name: "max",
134 arity: 2,
135 optional: false,
136 runtime_fn: "nerd_max",
137 hint: "nerd.max(a, b)",
138 },
139 ModuleFn {
140 name: "pow",
141 arity: 2,
142 optional: false,
143 runtime_fn: "nerd_pow",
144 hint: "nerd.pow(base, exponent)",
145 },
146 ],
147 consts: &[
148 ("pi", "Value::Float(std::f64::consts::PI)"),
149 ("e", "Value::Float(std::f64::consts::E)"),
150 ],
151 },
152 Module {
153 name: "strings",
154 funcs: &[
155 ModuleFn {
156 name: "beeg",
157 arity: 1,
158 optional: false,
159 runtime_fn: "strings_beeg",
160 hint: "strings.beeg(s)",
161 },
162 ModuleFn {
163 name: "smoll",
164 arity: 1,
165 optional: false,
166 runtime_fn: "strings_smoll",
167 hint: "strings.smoll(s)",
168 },
169 ModuleFn {
170 name: "trim",
171 arity: 1,
172 optional: false,
173 runtime_fn: "strings_trim",
174 hint: "strings.trim(s)",
175 },
176 ModuleFn {
177 name: "split",
178 arity: 2,
179 optional: false,
180 runtime_fn: "strings_split",
181 hint: "strings.split(s, sep)",
182 },
183 ModuleFn {
184 name: "join",
185 arity: 2,
186 optional: false,
187 runtime_fn: "strings_join",
188 hint: "strings.join(parts, sep)",
189 },
190 ModuleFn {
191 name: "contains",
192 arity: 2,
193 optional: false,
194 runtime_fn: "strings_contains",
195 hint: "strings.contains(s, needle)",
196 },
197 ModuleFn {
198 name: "replace",
199 arity: 3,
200 optional: false,
201 runtime_fn: "strings_replace",
202 hint: "strings.replace(s, from, to)",
203 },
204 ],
205 consts: &[],
206 },
207 Module {
208 name: "hunt",
209 funcs: &[
210 ModuleFn {
211 name: "test",
212 arity: 2,
213 optional: false,
214 runtime_fn: "hunt_test",
215 hint: "hunt.test(pat, text)",
216 },
217 ModuleFn {
218 name: "find",
219 arity: 2,
220 optional: false,
221 runtime_fn: "hunt_find",
222 hint: "hunt.find(pat, text)",
223 },
224 ModuleFn {
225 name: "find_all",
226 arity: 2,
227 optional: false,
228 runtime_fn: "hunt_find_all",
229 hint: "hunt.find_all(pat, text)",
230 },
231 ModuleFn {
232 name: "groups",
233 arity: 2,
234 optional: false,
235 runtime_fn: "hunt_groups",
236 hint: "hunt.groups(pat, text)",
237 },
238 ModuleFn {
239 name: "replace",
240 arity: 3,
241 optional: false,
242 runtime_fn: "hunt_replace",
243 hint: "hunt.replace(pat, text, repl)",
244 },
245 ],
246 consts: &[],
247 },
248 Module {
249 name: "fetch",
250 funcs: &[
251 ModuleFn {
252 name: "read",
253 arity: 1,
254 optional: false,
255 runtime_fn: "fetch_read",
256 hint: "fetch.read(path)",
257 },
258 ModuleFn {
259 name: "write",
260 arity: 2,
261 optional: false,
262 runtime_fn: "fetch_write",
263 hint: "fetch.write(path, text)",
264 },
265 ModuleFn {
266 name: "append",
267 arity: 2,
268 optional: false,
269 runtime_fn: "fetch_append",
270 hint: "fetch.append(path, text)",
271 },
272 ModuleFn {
273 name: "read_bytes",
274 arity: 1,
275 optional: false,
276 runtime_fn: "fetch_read_bytes",
277 hint: "fetch.read_bytes(path)",
278 },
279 ModuleFn {
280 name: "write_bytes",
281 arity: 2,
282 optional: false,
283 runtime_fn: "fetch_write_bytes",
284 hint: "fetch.write_bytes(path, bytes)",
285 },
286 ModuleFn {
287 name: "exists",
288 arity: 1,
289 optional: false,
290 runtime_fn: "fetch_exists",
291 hint: "fetch.exists(path)",
292 },
293 ModuleFn {
294 name: "delete",
295 arity: 1,
296 optional: false,
297 runtime_fn: "fetch_delete",
298 hint: "fetch.delete(path)",
299 },
300 ModuleFn {
301 name: "list",
302 arity: 1,
303 optional: false,
304 runtime_fn: "fetch_list",
305 hint: "fetch.list(path)",
306 },
307 ModuleFn {
308 name: "make_dir",
309 arity: 1,
310 optional: false,
311 runtime_fn: "fetch_make_dir",
312 hint: "fetch.make_dir(path)",
313 },
314 ModuleFn {
315 name: "remove_dir",
316 arity: 1,
317 optional: false,
318 runtime_fn: "fetch_remove_dir",
319 hint: "fetch.remove_dir(path)",
320 },
321 ModuleFn {
322 name: "rename",
323 arity: 2,
324 optional: false,
325 runtime_fn: "fetch_rename",
326 hint: "fetch.rename(from, to)",
327 },
328 ModuleFn {
329 name: "copy",
330 arity: 2,
331 optional: false,
332 runtime_fn: "fetch_copy",
333 hint: "fetch.copy(from, to)",
334 },
335 ModuleFn {
336 name: "stat",
337 arity: 1,
338 optional: false,
339 runtime_fn: "fetch_stat",
340 hint: "fetch.stat(path)",
341 },
342 ModuleFn {
343 name: "join",
344 arity: 2,
345 optional: false,
346 runtime_fn: "fetch_join",
347 hint: "fetch.join(a, b)",
348 },
349 ModuleFn {
350 name: "basename",
351 arity: 1,
352 optional: false,
353 runtime_fn: "fetch_basename",
354 hint: "fetch.basename(path)",
355 },
356 ModuleFn {
357 name: "ext",
358 arity: 1,
359 optional: false,
360 runtime_fn: "fetch_ext",
361 hint: "fetch.ext(path)",
362 },
363 ],
364 consts: &[],
365 },
366 Module {
367 name: "env",
368 funcs: &[
369 ModuleFn {
370 name: "args",
371 arity: 0,
372 optional: false,
373 runtime_fn: "env_args",
374 hint: "env.args()",
375 },
376 ModuleFn {
377 name: "get",
378 arity: 1,
379 optional: false,
380 runtime_fn: "env_get",
381 hint: "env.get(name)",
382 },
383 ],
384 consts: &[],
385 },
386 Module {
387 name: "howl",
388 funcs: &[
389 ModuleFn {
390 name: "listen",
391 arity: 2,
392 optional: false,
393 runtime_fn: "howl_listen",
394 hint: "howl.listen(host, port)",
395 },
396 ModuleFn {
397 name: "connect",
398 arity: 2,
399 optional: false,
400 runtime_fn: "howl_connect",
401 hint: "howl.connect(host, port)",
402 },
403 ModuleFn {
404 name: "accept",
405 arity: 1,
406 optional: false,
407 runtime_fn: "howl_accept",
408 hint: "howl.accept(listener)",
409 },
410 ModuleFn {
411 name: "port",
412 arity: 1,
413 optional: false,
414 runtime_fn: "howl_port",
415 hint: "howl.port(sock)",
416 },
417 ModuleFn {
418 name: "send",
419 arity: 2,
420 optional: false,
421 runtime_fn: "howl_send",
422 hint: "howl.send(conn, text)",
423 },
424 ModuleFn {
425 name: "send_bytes",
426 arity: 2,
427 optional: false,
428 runtime_fn: "howl_send_bytes",
429 hint: "howl.send_bytes(conn, bytes)",
430 },
431 ModuleFn {
432 name: "recv",
433 arity: 2,
434 optional: false,
435 runtime_fn: "howl_recv",
436 hint: "howl.recv(conn, max_bytes)",
437 },
438 ModuleFn {
439 name: "recv_bytes",
440 arity: 2,
441 optional: false,
442 runtime_fn: "howl_recv_bytes",
443 hint: "howl.recv_bytes(conn, max_bytes)",
444 },
445 ModuleFn {
446 name: "recv_line",
447 arity: 1,
448 optional: false,
449 runtime_fn: "howl_recv_line",
450 hint: "howl.recv_line(conn)",
451 },
452 ModuleFn {
453 name: "close",
454 arity: 1,
455 optional: false,
456 runtime_fn: "howl_close",
457 hint: "howl.close(sock)",
458 },
459 ModuleFn {
460 name: "get",
461 arity: 1,
462 optional: false,
463 runtime_fn: "howl_get",
464 hint: "howl.get(url)",
465 },
466 ModuleFn {
467 name: "post",
468 arity: 2,
469 optional: false,
470 runtime_fn: "howl_post",
471 hint: "howl.post(url, body)",
472 },
473 ModuleFn {
474 name: "request",
475 arity: 2,
476 optional: true,
477 runtime_fn: "howl_request",
478 hint: "howl.request(method, url) or howl.request(method, url, opts)",
479 },
480 ],
481 consts: &[],
482 },
483 Module {
484 name: "json",
485 funcs: &[
486 ModuleFn {
487 name: "parse",
488 arity: 1,
489 optional: false,
490 runtime_fn: "json_parse",
491 hint: "json.parse(text)",
492 },
493 ModuleFn {
494 name: "emit",
495 arity: 1,
496 optional: false,
497 runtime_fn: "json_emit",
498 hint: "json.emit(value)",
499 },
500 ],
501 consts: &[],
502 },
503 Module {
504 name: "dson",
505 funcs: &[
506 ModuleFn {
507 name: "parse",
508 arity: 1,
509 optional: false,
510 runtime_fn: "dson_parse",
511 hint: "dson.parse(text)",
512 },
513 ModuleFn {
514 name: "emit",
515 arity: 1,
516 optional: false,
517 runtime_fn: "dson_emit",
518 hint: "dson.emit(value)",
519 },
520 ],
521 consts: &[],
522 },
523 Module {
524 name: "nap",
525 funcs: &[
526 ModuleFn {
527 name: "now",
528 arity: 0,
529 optional: false,
530 runtime_fn: "nap_now",
531 hint: "nap.now()",
532 },
533 ModuleFn {
534 name: "mono",
535 arity: 0,
536 optional: false,
537 runtime_fn: "nap_mono",
538 hint: "nap.mono()",
539 },
540 ModuleFn {
541 name: "rest",
542 arity: 1,
543 optional: false,
544 runtime_fn: "nap_rest",
545 hint: "nap.rest(seconds)",
546 },
547 ModuleFn {
548 name: "stamp",
549 arity: 1,
550 optional: false,
551 runtime_fn: "nap_stamp",
552 hint: "nap.stamp(secs)",
553 },
554 ModuleFn {
555 name: "parse",
556 arity: 1,
557 optional: false,
558 runtime_fn: "nap_parse",
559 hint: "nap.parse(text)",
560 },
561 ],
562 consts: &[],
563 },
564 Module {
565 name: "pack",
566 funcs: &[
567 ModuleFn {
571 name: "zoom",
572 arity: 2,
573 optional: false,
574 runtime_fn: PACK_ZOOM_RUNTIME_FN,
575 hint: "pack.zoom(f, [args])",
576 },
577 ModuleFn {
578 name: "fetch",
579 arity: 1,
580 optional: false,
581 runtime_fn: "pack_fetch",
582 hint: "pack.fetch(pup)",
583 },
584 ModuleFn {
585 name: "bowl",
586 arity: 0,
587 optional: false,
588 runtime_fn: "pack_bowl",
589 hint: "pack.bowl()",
590 },
591 ModuleFn {
592 name: "drop",
593 arity: 2,
594 optional: false,
595 runtime_fn: "pack_drop",
596 hint: "pack.drop(bowl, value)",
597 },
598 ModuleFn {
599 name: "sniff",
600 arity: 1,
601 optional: false,
602 runtime_fn: "pack_sniff",
603 hint: "pack.sniff(bowl)",
604 },
605 ],
606 consts: &[],
607 },
608 Module {
609 name: "chase",
610 funcs: &[ModuleFn {
611 name: "run",
612 arity: 3,
613 optional: false,
614 runtime_fn: "chase_run",
615 hint: "chase.run(cmd, args, stdin)",
616 }],
617 consts: &[],
618 },
619 Module {
620 name: "roll",
621 funcs: &[
622 ModuleFn {
623 name: "seed",
624 arity: 1,
625 optional: false,
626 runtime_fn: "roll_seed",
627 hint: "roll.seed(n)",
628 },
629 ModuleFn {
630 name: "int",
631 arity: 2,
632 optional: false,
633 runtime_fn: "roll_int",
634 hint: "roll.int(low, high)",
635 },
636 ModuleFn {
637 name: "float",
638 arity: 0,
639 optional: false,
640 runtime_fn: "roll_float",
641 hint: "roll.float()",
642 },
643 ModuleFn {
644 name: "choice",
645 arity: 1,
646 optional: false,
647 runtime_fn: "roll_choice",
648 hint: "roll.choice(list)",
649 },
650 ModuleFn {
651 name: "shuffle",
652 arity: 1,
653 optional: false,
654 runtime_fn: "roll_shuffle",
655 hint: "roll.shuffle(list)",
656 },
657 ModuleFn {
658 name: "sample",
659 arity: 2,
660 optional: false,
661 runtime_fn: "roll_sample",
662 hint: "roll.sample(list, k)",
663 },
664 ],
665 consts: &[],
666 },
667 Module {
668 name: "crypto",
669 funcs: &[
670 ModuleFn {
671 name: "sha256",
672 arity: 1,
673 optional: false,
674 runtime_fn: "crypto_sha256",
675 hint: "crypto.sha256(data)",
676 },
677 ModuleFn {
678 name: "hmac_sha256",
679 arity: 2,
680 optional: false,
681 runtime_fn: "crypto_hmac_sha256",
682 hint: "crypto.hmac_sha256(key, data)",
683 },
684 ModuleFn {
685 name: "token",
686 arity: 1,
687 optional: false,
688 runtime_fn: "crypto_token",
689 hint: "crypto.token(n)",
690 },
691 ModuleFn {
692 name: "same",
693 arity: 2,
694 optional: false,
695 runtime_fn: "crypto_same",
696 hint: "crypto.same(a, b)",
697 },
698 ],
699 consts: &[],
700 },
701];