Ely Office: six offline-first desktop apps in Rust and GPUI

ElyDoc, ElyTable, ElyShow (LibreOfficeKit), ElyPDF (MuPDF), ElyTree (Git),
ElyMark (Milkdown and CodeMirror in CEF). ElyMail and ElyAgent follow.
This commit is contained in:
ZacharyZhang-NY committed 2026-10-08 21:20:08 -04:00
commit b7fca0146d
817 files changed
+143101

No files matched your search

+187
View File
@@ -0,0 +1,187 @@
//! Framed requests between an app and its engine worker.
mod relay;
pub use relay::{Relay, relay};
use std::io::{self, Read, Write};
/// A frame: u32 length, u8 tag, u64 request id, payload.
pub const MAX_FRAME: usize = 64 * 1024 * 1024;
/// Frames no request asked for, such as pushed events.
pub const UNASKED: u64 = 0;
/// Writes one frame and flushes; replies carry the request's id.
pub fn write_frame(out: &mut impl Write, tag: u8, id: u64, payload: &[u8]) -> io::Result<()> {
// The reader's cap, checked before a byte goes out.
if payload.len() > MAX_FRAME {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
format!("a {} byte frame is over the {MAX_FRAME} byte cap", payload.len()),
));
}
let len = payload.len() as u32;
out.write_all(&len.to_le_bytes())?;
out.write_all(&[tag])?;
out.write_all(&id.to_le_bytes())?;
out.write_all(payload)?;
out.flush()
}
/// A reply with another request's id means the pairing broke.
pub fn check_reply(asked: u64, got: u64) -> io::Result<()> {
match asked == got {
true => Ok(()),
false => Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("the worker answered request {got}, not {asked}"),
)),
}
}
/// Reads (tag, id, payload); None at a clean stream end.
pub fn read_frame(input: &mut impl Read) -> io::Result<Option<(u8, u64, Vec<u8>)>> {
let mut len = [0u8; 4];
// Only a stream ending between frames ends cleanly.
let mut got = 0;
while got < len.len() {
match input.read(&mut len[got..]) {
Ok(0) if got == 0 => return Ok(None),
Ok(0) => return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "a cut frame header")),
Ok(read) => got += read,
Err(error) if error.kind() == io::ErrorKind::Interrupted => {}
Err(error) => return Err(error),
}
}
let len = u32::from_le_bytes(len) as usize;
if len > MAX_FRAME {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"frame over the cap",
));
}
let mut tag = [0u8; 1];
input.read_exact(&mut tag)?;
let mut id = [0u8; 8];
input.read_exact(&mut id)?;
let mut payload = vec![0u8; len];
input.read_exact(&mut payload)?;
Ok(Some((tag[0], u64::from_le_bytes(id), payload)))
}
/// A payload writer.
#[derive(Default)]
pub struct Pack {
bytes: Vec<u8>,
}
impl Pack {
pub fn new() -> Self {
Self::default()
}
pub fn str(self, text: &str) -> Self {
self.blob(text.as_bytes())
}
/// Length-prefixed raw bytes.
pub fn blob(mut self, data: &[u8]) -> Self {
self.bytes
.extend_from_slice(&(data.len() as u32).to_le_bytes());
self.bytes.extend_from_slice(data);
self
}
pub fn u64(mut self, value: u64) -> Self {
self.bytes.extend_from_slice(&value.to_le_bytes());
self
}
pub fn i64(mut self, value: i64) -> Self {
self.bytes.extend_from_slice(&value.to_le_bytes());
self
}
pub fn bytes(self) -> Vec<u8> {
self.bytes
}
}
/// A payload reader.
pub struct Unpack<'a> {
bytes: &'a [u8],
at: usize,
}
impl<'a> Unpack<'a> {
pub fn new(bytes: &'a [u8]) -> Self {
Self { bytes, at: 0 }
}
fn take(&mut self, len: usize) -> io::Result<&'a [u8]> {
let end = self.at + len;
let Some(slice) = self.bytes.get(self.at..end) else {
return Err(io::Error::new(io::ErrorKind::InvalidData, "a short frame"));
};
self.at = end;
Ok(slice)
}
pub fn str(&mut self) -> io::Result<String> {
String::from_utf8(self.blob()?)
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "payload is no text"))
}
/// Length-prefixed raw bytes.
pub fn blob(&mut self) -> io::Result<Vec<u8>> {
let len = u32::from_le_bytes(self.take(4)?.try_into().expect("a u32")) as usize;
Ok(self.take(len)?.to_vec())
}
pub fn u64(&mut self) -> io::Result<u64> {
Ok(u64::from_le_bytes(self.take(8)?.try_into().expect("a u64")))
}
pub fn i64(&mut self) -> io::Result<i64> {
Ok(i64::from_le_bytes(
self.take(8)?.try_into().expect("an i64"),
))
}
/// The unread tail.
pub fn rest(&self) -> &'a [u8] {
&self.bytes[self.at..]
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn frames_and_payloads_round_trip_and_short_ones_fail() {
let payload = Pack::new().str("页 one").u64(7).i64(-3).blob(&[1, 2]).bytes();
let mut wire = Vec::new();
write_frame(&mut wire, 9, 41, &payload).expect("writes");
let mut read = &wire[..];
let (tag, id, back) = read_frame(&mut read).expect("reads").expect("a frame");
assert_eq!((tag, id), (9, 41));
assert!(check_reply(41, id).is_ok());
assert_eq!(check_reply(42, id).expect_err("another request").kind(), io::ErrorKind::InvalidData);
let mut unpack = Unpack::new(&back);
assert_eq!(unpack.str().expect("text"), "页 one");
assert_eq!((unpack.u64().expect("u64"), unpack.i64().expect("i64")), (7, -3));
assert_eq!(unpack.blob().expect("blob"), [1, 2]);
assert!(unpack.rest().is_empty());
assert!(unpack.u64().is_err(), "a short payload is an error");
assert!(read_frame(&mut &[][..]).expect("a clean end").is_none());
let mut nothing = Vec::new();
let over = write_frame(&mut nothing, 9, 1, &vec![0; MAX_FRAME + 1]).expect_err("over the cap");
assert_eq!(over.kind(), io::ErrorKind::InvalidInput);
assert!(nothing.is_empty(), "nothing written");
for cut in 1..4 {
let failed = read_frame(&mut &wire[..cut]).expect_err("a cut header");
assert_eq!(failed.kind(), io::ErrorKind::UnexpectedEof, "{cut} bytes");
}
}
}
+87
View File
@@ -0,0 +1,87 @@
//! A worker's stderr, carried into the app's log.
use std::{
io::{BufRead as _, BufReader, Read},
sync::{Arc, Mutex},
thread::JoinHandle,
};
/// The relaying thread, and the worker's last error record.
pub struct Relay {
last: Arc<Mutex<Option<String>>>,
thread: Option<JoinHandle<()>>,
}
impl Relay {
/// After the worker exits: its last error record.
pub fn last_error(&mut self) -> Option<String> {
if let Some(thread) = self.thread.take() {
let _ = thread.join();
}
self.last.lock().expect("the relay lock").clone()
}
}
/// Logs the worker's own records; engine text stays out.
pub fn relay(stderr: impl Read + Send + 'static, who: &'static str) -> Relay {
let last = Arc::new(Mutex::new(None));
let kept = Arc::clone(&last);
let thread = std::thread::spawn(move || {
let mut withheld = 0u64;
for line in BufReader::new(stderr).lines() {
let line = match line {
Ok(line) => line,
Err(error) => return log::warn!(target: who, "stderr unreadable: {error}"),
};
match parse(&line) {
Some((level, target, message)) => {
if level == log::Level::Error {
*kept.lock().expect("the relay lock") = Some(message.to_string());
}
log::log!(target: target, level, "{message}")
}
// A crash stack names code, never documents.
None if frame(&line) => log::error!(target: who, "{line}"),
None => {
withheld += 1;
log::debug!(target: who, "native output withheld ({withheld} lines)");
}
}
}
});
Relay { last, thread: Some(thread) }
}
/// `[time LEVEL target] message`, as env_logger writes it.
fn parse(line: &str) -> Option<(log::Level, &str, &str)> {
let (head, message) = line.strip_prefix('[')?.split_once("] ")?;
let mut words = head.split_whitespace();
let (_, level, target) = (words.next()?, words.next()?, words.next()?);
Some((level.parse().ok()?, target, message))
}
/// `3 ely-lok-worker 0x0001 symbol + 12` from backtrace_symbols_fd.
fn frame(line: &str) -> bool {
let mut words = line.split_whitespace();
words.next().is_some_and(|n| n.parse::<u32>().is_ok())
&& words.next().is_some()
&& words.next().is_some_and(|address| address.starts_with("0x"))
}
#[cfg(test)]
mod tests {
use super::{frame, parse};
#[test]
fn a_record_keeps_its_level_and_target() {
let line = "[2026-10-08T12:00:00Z WARN ely_lok::worker] request failed";
assert_eq!(parse(line), Some((log::Level::Warn, "ely_lok::worker", "request failed")));
assert_eq!(parse("warning: syntax error: unknown keyword: 'Zq'"), None);
}
#[test]
fn stack_frames_pass_and_engine_text_does_not() {
assert!(frame("3 ely-lok-worker 0x0000000104f3c960 report + 52"));
assert!(!frame("syntax error: unknown keyword: 'ZqxPrivate42'"));
}
}