Something went wrong. Try again.
An experimental alternative to Rust sans-io that enables the direct style
Something went wrong. Try again.
2.6 kB · 82 lines
Java
at main
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.charset.StandardCharsets;import java.util.ArrayList;import java.util.List;
/// The little-endian encoding shared with `ffi/rust/src/codec.rs`.final class Codec { /// An effect decoded from Rust. The encoding is the same for both machine /// kinds; how the awaited effect is answered differs per driver. sealed interface Effect { record Count() implements Effect {} record Lookup(String name) implements Effect {} record ReadLine() implements Effect {} record Sleep(long millis) implements Effect {} record Write(String text) implements Effect {} }
/// Decode a batch. static List<Effect> decode(byte[] bytes) { var buf = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN); var out = new ArrayList<Effect>();
while (buf.hasRemaining()) { int tag = buf.get() & 0xff; switch (tag) { case 1 -> out.add(new Effect.Count()); case 2 -> { var name = str(buf); out.add(new Effect.Lookup(name)); } case 3 -> out.add(new Effect.ReadLine()); case 4 -> { long millis = buf.getLong(); out.add(new Effect.Sleep(millis)); } case 5 -> out.add(new Effect.Write(str(buf))); default -> throw new IllegalStateException("unknown effect tag " + tag); } }
return out; }
private static String str(ByteBuffer buf) { int len = buf.getInt(); var bytes = new byte[len]; buf.get(bytes); return new String(bytes, StandardCharsets.UTF_8); }
/// Sans-io inputs. static byte[] start() { return new byte[] {0}; }
static byte[] line(String s) { return tagged(1, s); }
static byte[] greeting(String s) { return tagged(2, s); }
static byte[] woke() { return new byte[] {3}; }
static byte[] counted(int n) { return ByteBuffer.allocate(5).order(ByteOrder.LITTLE_ENDIAN).put((byte) 4).putInt(n).array(); }
private static byte[] tagged(int tag, String s) { var bytes = s.getBytes(StandardCharsets.UTF_8); return ByteBuffer.allocate(5 + bytes.length) .order(ByteOrder.LITTLE_ENDIAN) .put((byte) tag) .putInt(bytes.length) .put(bytes) .array(); }}