Data:JSON/TOML 与受检访问
Data 表示 JSON/TOML 的只读数据视图。读取后,按所需类型解码,再用于计算或生成正文;DataError 保存读取、解析或访问失败的信息。
解码后的标量可用 str 显式显示;Array<E> 可用 for 生成正文、表格行或列表项,见 标量显示与有限遍历。原始 Data 不直接可遍历或 stringify。
JSON 和受支持的 TOML 共用 Null | Bool | Int | Float | String | Array | Object 节点树。子树访问只复制句柄,保留数据内路径和来源;句柄不携带继续读取资源的能力。对象成员保留输入顺序,数据判等忽略来源,但保留对象与数组顺序。
读取与解析
fn read_json(source: Path) -> Result<Data, DataError>;
fn read_toml(source: Path) -> Result<Data, DataError>;
fn parse_json(text: String) -> Result<Data, DataError>;
fn parse_toml(text: String) -> Result<Data, DataError>;
readjson/readtoml 在 notc Code 执行时读取文件,授权规则见 Path 与文本读取。parsejson/parsetoml 解析已有字符串,也可在 comptime 中使用。
fn title(source: Path) -> String {
let root = data_expect<Data>(read_json(source));
data_expect<String>(data_require<String>(root, "title"))
}
显式目标类型
fn data_decode<T: Type>(data: Data) -> Result<T, DataError>;
T 必须在调用的 <> 中给出。允许 Data、Unit、Bool、Int、Float、String,以及这些类型递归组成的 Array<E>/Option<E>。
Data 返回同一节点的视图,不承诺它是对象。
Unit 只接收原始 Null;Option<E> 将 Null 解码为 none,将非 null 解码为 some(E)。这是解码边界规则,不是普通 notc 赋值或参数的隐式转换。
标量严格匹配种类,不自动解析数字字符串,不做 Int→Float 或标量→String 转换。
Array<E> 递归验证每个元素;Array<Data> 可以保存异构原始数组的节点句柄,不复制整棵子树。
Dict、擦除的 Array、Never、Result、DataError、Path、ResourceTarget、Type、Content 均不是解码目标,嵌套使用也不允许。空数组或 null 不会放宽限制。
解码结果保留调用时指定的完整静态类型。
对象与数组
fn data_require<T: Type>(object: Data, key: String) -> Result<T, DataError>;
fn data_get<T: Type>(object: Data, key: String) -> Result<Option<T>, DataError>;
fn data_has(object: Data, key: String) -> Result<Bool, DataError>;
fn data_keys(object: Data) -> Result<Array<String>, DataError>;
fn data_require_index<T: Type>(array: Data, index: Int) -> Result<T, DataError>;
fn data_index<T: Type>(array: Data, index: Int) -> Result<Option<T>, DataError>;
fn data_len(array: Data) -> Result<Int, DataError>;
fn data_kind(data: Data) -> String;
require 要求字段/索引存在,缺失时返回 err;get/index 在缺失/越界时返回 ok(none)。节点种类或值类型不符时均返回 err。has 检查对象是否有指定键,keys 按原顺序返回键;数组索引从 0 开始,负数报错。datalen 返回数组长度,datakind 返回节点种类名称。
原始 Null、字段缺失、语言 Unit 和 Option 的 none 不混用:
data_get<String>:缺失→ok(none),null→err,字符串 s→ok(some(s))。data_get<Option<String>>:缺失→ok(none),null→ok(some(none)),字符串 s→ok(some(some(s)))。data_require<Option<String>>:字段必须存在,但允许 null。
错误值与诊断升级
fn data_error_kind(error: DataError) -> String;
fn data_error_message(error: DataError) -> String;
fn data_error_path(error: DataError) -> String;
fn data_fail(error: DataError) -> Never;
fn data_expect<T: Type>(value: Result<T, DataError>) -> T;
dataexpect 成功时返回 T,失败时执行 datafail。也可用普通 Code 的 match 选择回退;被处理的 err 不留下构建错误诊断:
fn optional_title(source: Path) -> String {
match read_json(source) {
err(error) => "unavailable",
ok(root) => match data_get<String>(root, "title") {
err(error) => "invalid title",
ok(value) => match value { none => "untitled", some(title) => title },
},
}
}
错误类别使用稳定字符串,如 notfound、accessdenied、syntax、numberrange、duplicatekey、unsupportedvalue、typemismatch、missingkey、outofrange、invalidquery。dataerrorpath 使用 RFC 6901 路径,根为空字符串。
datafail 保留实际数据文件范围、同版本源码和读取/调用展开链;无精确节点范围时使用数据文件的空范围。纯文本解析或来源已移除的 wire 视图降级到升级调用点,不把数据内部偏移套到 notc 源码上。普通 panic(data_error_message(error)) 可用,但字符串化后不会恢复数据来源。
文件缺失、拒绝访问、非文件、普通 IO、UTF-8/格式和受检访问错误返回 err。Pending 仍是宿主 NeedResources,不能提前发布 fallback;缺少读取能力及文件/请求/缓存/解析/解码/求值的硬预算失败仍走宿主或求值失败通道,Result 不能捕获它们。
支持的格式
JSON 支持所有根种类;拒绝重复键和 UTF-8 BOM。整数语法必须在 i64 范围内,不能溢出后改作 Float;小数/指数语法按有限 f64 解码,不根据数值是否恰为整数改变类型。非有限或溢出结果拒绝。
TOML 根是 Object。支持 table、inline table、array、array of tables、string、bool、i64 和有限 f64。日期/时间/时区值及非有限浮点明确拒绝,不自动字符串化。TOML 解析库可能将某些格式/数字问题报告为 syntax。
输入与限额
同一轮构建共享已读取的数据,文件变化在下一轮构建生效。读取权限与输入接口见 资源输入与求值。
默认单数据输入和单逻辑值上限为 16 MiB,原始树/解码结果最多 250,000 个逻辑节点,数据深度为 64。解析工作集与批次数据缓存各限 128 MiB,缓存最多 4096 条目。
Rust 宿主可通过 Limits.valuebytes/Limits.data、Vault.withevaluationlimits、withinputlimits 和 withdatacachelimits 调整限额。
原始 Data/DataError 及包含它们的集合不能作为 <> 的值实参;它们的 Type 值可以作为类型实参。可在 comptime 解析/投影后传递普通标量或集合。
向 HTML 属性、组件参数或模板输出数据时,先选择所需字段并解码为普通值。inspection 对 Data/DataError 只展示摘要。
完整例子见仓库 examples/structured-data 与 cargo run --example structured_data。