···1+use std::str;
2+use typst_wasm_protocol::wasm_export;
3+4+// Simple string operation function
5+#[wasm_export]
6+fn to_uppercase(input: &[u8]) -> Vec<u8> {
7+ let input_str = match str::from_utf8(input) {
8+ Ok(s) => s,
9+ Err(_) => return b"Invalid UTF-8 input".to_vec(),
10+ };
11+12+ input_str.to_uppercase().into_bytes()
13+}
14+15+// Using custom export name
16+#[wasm_export(export_rename = "count_chars")]
17+fn count_characters(input: &[u8]) -> Vec<u8> {
18+ let input_str = match str::from_utf8(input) {
19+ Ok(s) => s,
20+ Err(_) => return b"Invalid UTF-8 input".to_vec(),
21+ };
22+23+ format!("Character count: {}", input_str.chars().count()).into_bytes()
24+}
25+26+// Function returning Result type
27+#[wasm_export]
28+fn divide_numbers(input: &[u8]) -> Result<String, String> {
29+ let input_str = str::from_utf8(input).map_err(|e| format!("UTF-8 error: {}", e))?;
30+31+ let numbers: Vec<&str> = input_str.split(',').collect();
32+ if numbers.len() != 2 {
33+ return Err("Expected two comma-separated numbers".to_string());
34+ }
35+36+ let a: f64 = numbers[0]
37+ .trim()
38+ .parse()
39+ .map_err(|_| "First value is not a valid number".to_string())?;
40+ let b: f64 = numbers[1]
41+ .trim()
42+ .parse()
43+ .map_err(|_| "Second value is not a valid number".to_string())?;
44+45+ if b == 0.0 {
46+ return Err("Cannot divide by zero".to_string());
47+ }
48+49+ let result = a / b;
50+ Ok(format!("Result: {:.2}", result))
51+}
52+53+// Function returning Result<String, String> type
54+#[wasm_export]
55+fn validate_email(input: &[u8]) -> Result<String, String> {
56+ let email = str::from_utf8(input)
57+ .map_err(|e| format!("UTF-8 error: {}", e))?
58+ .trim();
59+60+ // Simple email validation
61+ if !email.contains('@') || !email.contains('.') {
62+ return Err("Invalid email format".to_string());
63+ }
64+65+ Ok("Email is valid".to_string())
66+}
+3
src/lib.typ
···000
···1+// Should compile numbat_typst.wasm first
2+// using:
3+#import plugin("../target/wasm32-unknown-unknown/release/numbat_typst.wasm"): to_uppercase, count_chars, divide_numbers, validate_email
+27
tests/examples.typ
···000000000000000000000000000
···1+#import "@local/numbat:0.1.0": to_uppercase, count_chars, divide_numbers, validate_email
2+3+= Tests
4+5+Hi there!
6+7+#let input = "Hello, Typst!"
8+9+// Call the to_uppercase function
10+#let uppercase = str(to_uppercase(bytes(input)))
11+Original: #input\
12+Uppercase: #uppercase
13+14+// Call the count_chars function (note this is exported with a custom name)
15+#let char_count = str(count_chars(bytes(input)))
16+#char_count
17+18+// Call a function that returns a Result type
19+#let division_result = str(divide_numbers(bytes("10,2")))
20+#division_result
21+22+// Handle potential errors, uncomment to see the error handling in action
23+// #let division_error = divide_numbers(bytes("10,0"))
24+25+// Use a function with Result<String, String> type
26+#let email_valid = str(validate_email(bytes("user@example.com")))
27+Email validation: #email_valid