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
#![no_std]
use core::arch::wasm32::unreachable;
const BUF: usize = 4096;
static mut INPUT: [u8; BUF] = [0; BUF];
static mut OUTPUT: [u8; BUF] = [0; BUF];
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
unreachable()
}
#[unsafe(no_mangle)]
pub extern "C" fn input_ptr() -> *mut u8 {
(&raw mut INPUT).cast()
}
#[unsafe(no_mangle)]
pub extern "C" fn output_ptr() -> *mut u8 {
(&raw mut OUTPUT).cast()
}
#[unsafe(no_mangle)]
pub extern "C" fn run(len: i32) -> i32 {
let len = match usize::try_from(len) {
Ok(len) if len <= BUF => len,
_ => unreachable(),
};
let input = unsafe { core::slice::from_raw_parts((&raw const INPUT).cast::<u8>(), len) };
let output = unsafe { core::slice::from_raw_parts_mut(output_ptr(), BUF) };
let (Some(instance), Some(created_at)) =
(field(input, b"instance"), field(input, b"createdAt"))
else {
unreachable()
};
let mut out = Writer {
buf: output,
pos: 0,
};
out.put(b"{\"$type\":\"at.zkwid.demo.log\",\"text\":\"hello from ");
out.put(instance);
out.put(b"\",\"createdAt\":\"");
out.put(created_at);
out.put(b"\"}");
out.pos as i32
}
struct Writer<'a> {
buf: &'a mut [u8],
pos: usize,
}
impl Writer<'_> {
fn put(&mut self, bytes: &[u8]) {
let end = self.pos + bytes.len();
if end > self.buf.len() {
unreachable()
}
self.buf[self.pos..end].copy_from_slice(bytes);
self.pos = end;
}
}
fn field<'a>(json: &'a [u8], key: &[u8]) -> Option<&'a [u8]> {
let mut i = 0;
while i < json.len() {
if json[i] == b'"' {
let (s, next) = string(json, i)?;
i = skip_ws(json, next);
if json.get(i) == Some(&b':') {
i = skip_ws(json, i + 1);
if json.get(i) == Some(&b'"') {
let (v, next) = string(json, i)?;
if s == key {
return Some(v);
}
i = next;
}
}
} else {
i += 1;
}
}
None
}
fn string(json: &[u8], start: usize) -> Option<(&[u8], usize)> {
let rest = &json[start + 1..];
let end = rest.iter().position(|&b| b == b'"')?;
Some((&rest[..end], start + end + 2))
}
fn skip_ws(json: &[u8], mut i: usize) -> usize {
while json.get(i).is_some_and(|b| b.is_ascii_whitespace()) {
i += 1;
}
i
}