深入 Transity 源码:从 PureScript 到 Rust 重写的架构演进与设计哲学
深入 Transity 源码从 PureScript 到 Rust 重写的架构演进与设计哲学【免费下载链接】TransityKeep track of your , , , , on your command line with the plain text accounting tool of the future! 项目地址: https://gitcode.com/gh_mirrors/tr/TransityTransity 是一款基于纯文本文件的命令行复式记账工具用户只需用 YAML 编写账本journal就能在终端里跟踪现金、时间、股票等各类资产。本文是一次完整的 Transity 源码分析带你沿着从 PureScript 到 Rust 的重写路径理解这套面向未来的记账工具在数据模型、CLI 架构、精确计算与 Web 化四个维度的设计取舍。无论你是复式记账爱好者还是对函数式语言向系统语言迁移感兴趣的程序员这篇文章都能让你快速读懂它的架构全貌。Transity 是什么纯文本复式记账的未来形态与传统记账软件不同Transity 把账本数据保存在纯文本文件中examples/journal.yaml 就是一个标准示例用实体 账户 转账的模型描述每一笔资金流动。它天然支持多币种、多时间维度和分层账户结构所有数据都肉眼可读、可版本管理这正是plain text accounting运动的核心理念。源码目录总览两套实现并存的双轨架构打开仓库你会发现一个有趣的现象purescript/与src/两个目录并存分别承载着旧版与新版的完整实现。这种新旧同仓的布局让重写过程中的对比与回退变得异常方便。维度PureScript 版Rust 版核心目录purescript/src/src/入口文件Main.pursmain.rsCLI 框架自研 Oclis 库clap 4金额精度BigIntnum-bigint num-rationalWeb 支持编译为 JS 的简单页面Leptos axum WASMPureScript 时代的设计遗产旧版的核心是纯函数式设计。在 purescript/src/Transity/Data/ 下账本被拆分为Account、Amount、Balance、Ledger、Transaction、Transfer等模块每个模块都是不可变数据与纯函数的组合副作用被严格隔离。最值得学习的是 purescript/src/Oclis/ 这套自研 CLI 框架它把命令行参数解析拆成Tokenizer分词、Parser语法分析、Executor执行三层用声明式的方式描述每个子命令的参数与行为。CLI 的所有输出都是计算出字符串这种纯函数测试起来极其舒服。Rust 重写的核心动机从解释器到单二进制PureScript 版本编译后依赖 Node.js 运行时安装和分发都带着不小的包袱。而 Rust 版本的目标非常明确产出单一的原生可执行文件零运行时依赖。从 Cargo.toml 可以看到项目通过 feature 开关把cli、ssr、hydrate、wasm四种构建形态切得干干净净同一套核心代码既能编译成命令行工具也能编译成 WASM 跑在浏览器里。性能上的提升同样显著。PureScript 版的金额运算需要经过 JS 运行时中转而 Rust 版直接用BigRational做精确运算账本解析、日期过滤、标签筛选的速度都提升了一个量级。数据模型设计Amount 与 BigRational 的精确之道记账软件最不能容忍的就是浮点误差。在 src/lib.rs 中Amount结构体由BigRational任意精度有理数和commodity币种字符串组成digits_to_rational函数把12.3456这样的字符串精确转换为分数形式彻底杜绝了0.1 0.2 ! 0.3这类经典问题。CommodityMap是BTreeMapString, Amount的类型别名天然支持多币种并行记账同一个账户里欧元、美元、小时数可以并存互不干扰余额查询时会按币种分别汇总。Ledger 核心解析、校验与过滤流水线账本加载是一条清晰的流水线serde_yaml反序列化为LedgerRaw再由Ledger::from_raw做账户 ID 规范化:与/分隔符的兼容转换、实体与转账的校验最后通过filter_by_date和filter_by_tags生成过滤后的视图。src/lib.rs 中的TagExpr是一棵布尔表达式树支持person and store、not store、(person or user) and store这类带括号的复杂标签查询解析器用递归下降法实现代码只有不到 100 行却覆盖了完整的运算符优先级。CLI 层的演进从 Oclis 到 clap 的 20 个实用子命令新版 CLI 用 clap 的 derive 宏定义在 src/main.rs一共提供 20 个左右的子命令查询类balance、balance-all、transactions、transfers、entries、entries-by-account导出类csv、tsv、xlsx、ledger-entries可视化类gplot、gplot-cumul生成 gnuplot 图表代码管理类entities、entities-sorted、files、unused-files、server每个子命令都支持--begin、--end、--owner、--tag四个统一过滤参数使用体验高度一致。输出与可视化终端里的美学家终端输出是 Transity 的招牌。show_balance系列函数会计算所有列的宽度账户名、整数位、小数位、币种再逐列对齐正负金额分别用绿色与红色显示分组账户用青色反白标出阅读体验远超普通表格工具。gplot和gplot-cumul命令则更进一步直接把账本数据转换为 gnuplot 脚本在终端里就能画出逐笔收支和累计净资产的曲线图。Web 化Leptos axum WASM 的现代组合重写最大的惊喜在 Web 端。核心逻辑在 src/wasm.rs 中通过wasm_bindgen暴露给浏览器src/app.rs 用 Leptos 构建前端界面src/server.rs 用 axum 提供 SSR 服务。也就是说同一份lib.rs核心代码既是 CLI、又是 WASM、还能作为 Web 服务运行一次编写多处部署的架构红利在这里体现得淋漓尽致。测试策略快照测试守护重构安全重写过程中最怕行为漂移。项目在 tests/cli_snapshots.rs 中部署了 insta 快照测试体系tests/snapshots/ 下保存了balance、transactions、csv、tsv等所有子命令的期望输出。只要重构导致任何一处输出格式变化测试立刻亮起红灯这正是新旧同仓策略能顺利落地的保障。设计哲学总结这次重写告诉我们什么回看整个架构演进可以提炼出三条清晰的哲学精确优先金额永远用有理数而非浮点数这是记账工具的底线纯文本优先数据格式简单可读让账本成为可以长期保存的资产核心复用把数据模型、解析、校验做成与界面无关的核心库让 CLI、WASM、Web 共享同一套逻辑。从 PureScript 到 Rust改变的不仅是语言和性能更是一次对工具的本质是什么的重新思考。Transity 用实际代码证明一个命令行记账工具也可以拥有严谨的类型系统、精确的数值计算和优雅的架构分层。如果你正在研究纯文本记账、复式记账的数据建模或者正在规划自己项目的语言重写这份源码值得反复研读。克隆仓库https://gitcode.com/gh_mirrors/tr/Transity后对照 purescript/src/ 与 src/ 逐模块对比你会收获比任何教程都更深入的理解。【免费下载链接】TransityKeep track of your , , , , on your command line with the plain text accounting tool of the future! 项目地址: https://gitcode.com/gh_mirrors/tr/Transity创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考