Imported from the spike branch, with: - a library crate (Host API) for the CLI and the tests - JSON test scenarios for candidates - commit on close only for new or truncated files - a Nix flake: nix run -- init, nix run -- run
38 lines
1.4 KiB
Rust
38 lines
1.4 KiB
Rust
//! Keeps a list of notes in /data/notes.json and publishes them as
|
|
//! /public/notes.txt.
|
|
use serde_json::{Value, json};
|
|
use std::io::{BufRead, Write};
|
|
|
|
const DATA: &str = "/data/notes.json";
|
|
|
|
fn save(notes: &[String]) {
|
|
std::fs::write(DATA, serde_json::to_string(notes).unwrap()).unwrap();
|
|
std::fs::write("/public/notes.txt", notes.join("\n") + "\n").unwrap();
|
|
}
|
|
|
|
fn main() {
|
|
let mut notes: Vec<String> = std::fs::read_to_string(DATA)
|
|
.ok()
|
|
.and_then(|s| serde_json::from_str(&s).ok())
|
|
.unwrap_or_default();
|
|
let mut out = std::io::stdout().lock();
|
|
for line in std::io::stdin().lock().lines() {
|
|
let Ok(line) = line else { break };
|
|
let Ok(msg) = serde_json::from_str::<Value>(&line) else { continue };
|
|
let body = &msg["body"];
|
|
let reply = match body["type"].as_str() {
|
|
Some("shutdown") => break,
|
|
Some("add") => {
|
|
notes.push(body["text"].as_str().unwrap_or_default().to_string());
|
|
save(¬es);
|
|
json!({"type": "added", "count": notes.len()})
|
|
}
|
|
Some("list") => json!({"type": "notes", "items": notes}),
|
|
Some("crash") => panic!("asked to crash"),
|
|
_ => json!({"type": "error", "reason": "unknown message"}),
|
|
};
|
|
writeln!(out, "{}", json!({"to": msg["from"], "reply_to": msg["id"], "body": reply})).unwrap();
|
|
out.flush().unwrap();
|
|
}
|
|
}
|