// jeeflow-core/json —— 薄壳(方案 §2.2):builtin Json + @json.parse/stringify 承载,
// 语义对齐 rust json.rs(as_i64 双收 string、空输入→Null);FlowData=Map[String,Json] 载体。
///|
pub fn parse_json(input : String) -> Json raise @error.JeeflowError {
let trimmed = input.trim(chars=" \t\r\n")
if trimmed.is_empty() {
return null_json()
}
try {
@cjson.parse(trimmed)
} catch {
// issues/137-G/139:对外只给 java 逐字基准文案,cjson 的原文收进 detail()(门面顶层据此落日志)。
// 旧形状是 ParseError("json: \{e}") ⇒ 出口 msg 实测 = `解析错误: json: `,
// 与"内部信息不进 msg"口径相反(其余七栈这条早已各自收敛到固定文案+cause 分离)。
e => raise @error.JeeflowError::ParseErrorWithCause(
"读取流程定义 JSON 失败", "json: \{e}"
)
}
}
///|
pub fn stringify(value : Json) -> String {
value.stringify()
}
///|
pub fn get(value : Json, key : String) -> Json? {
// `Json.value` 已弃办,建议形就是这一句;本仓所有"取对象键"都从这里过,
// 所以只改这一处,其余 70+ 个 `.value(` 站点交给菜谱换成 @json.get(...)。
if value is Object(obj) {
obj.get(key)
} else {
None
}
}
///|
pub fn as_str(value : Json) -> String? {
// 同上:`Json.as_string` 已弃办
if value is String(s) {
Some(s)
} else {
None
}
}
///|
/// `Json.as_array` 的替身(本仓原来没有这一档,三个调用点各写一遍判形不如集中一处)
pub fn as_array(value : Json) -> Array[Json]? {
if value is Array(a) {
Some(a)
} else {
None
}
}
///|
/// 对齐 rust as_i64:Number 截断 / Str 解析双收。
/// Number 的 double 分量对 >2^53 整数会取整(雪花 id 均超限);
/// core 词法器对超限字面量在 repr 保留原文,有 repr 时按原文精确解析
/// (修复"任务不存在 …048"取整事故,见仓根 MAINTAINING.md §4 代决策 D-M5-3)
pub fn as_i64(value : Json) -> Int64? {
match value {
Json::Number(n, repr~) =>
match repr {
Some(s) =>
// 有 repr 就按原文精确解析;解析失败回退 double 分量(>2^53 会取整,故 repr 优先)
Some(try @string.parse_int64(s) catch {
_ => n.to_int64()
} noraise {
v => v
})
None => Some(n.to_int64())
}
Json::String(s) =>
try @string.parse_int64(s) catch {
_ => None
} noraise {
v => Some(v)
}
_ => None
}
}
///|
pub fn as_f64(value : Json) -> Double? {
match value {
Json::Number(n, ..) => Some(n)
Json::String(s) =>
try @string.parse_double(s) catch {
_ => None
} noraise {
v => Some(v)
}
_ => None
}
}
///|
pub fn as_bool(value : Json) -> Bool? {
match value {
Json::True => Some(true)
Json::False => Some(false)
_ => None
}
}
///|
pub fn get_str(value : Json, key : String) -> String? {
match get(value, key) {
Some(v) => as_str(v)
None => None
}
}
///|
pub fn get_i64(value : Json, key : String) -> Int64? {
match get(value, key) {
Some(v) => as_i64(v)
None => None
}
}
// ── Json 构建助手(builtin Json 为 pub 只读枚举,外部不能直呼构造器;
// 统一经 @cjson.parse 种子 + as_* 取底层容器原地写,实测引用语义)──
///|
pub fn null_json() -> Json {
try @cjson.parse("null") catch {
_ => abort("unreachable: literal null parse")
} noraise {
v => v
}
}
///|
pub fn number_of(n : Int64) -> Json {
// Int64::to_json() 在 core 里输出字符串(大整数安全惯例);本仓契约数字键走
// parse 原文 → Number 且 repr 保留原文(>2^53 安全),信封 code/pageNum 等保持 number
try @cjson.parse(n.to_string()) catch {
_ => number_f_of(0.0)
} noraise {
v => v
}
}
///|
pub fn number_f_of(n : Double) -> Json {
n.to_json()
}
///|
pub fn string_of(s : String) -> Json {
s.to_json()
}
///|
pub fn bool_of(b : Bool) -> Json {
b.to_json()
}
///|
pub fn empty_object() -> Json {
try @cjson.parse("{}") catch {
_ => abort("unreachable: literal {} parse")
} noraise {
v => v
}
}
///|
pub fn empty_array() -> Json {
try @cjson.parse("[]") catch {
_ => abort("unreachable: literal [] parse")
} noraise {
v => v
}
}
///|
/// 向对象写键(obj 必须来自 empty_object()/解析出的 Object)
pub fn obj_set(obj : Json, key : String, value : Json) -> Unit {
match obj {
Json::Object(m) => m[key] = value
_ => ()
}
}
///|
/// 向数组追加
pub fn arr_push(arr : Json, value : Json) -> Unit {
match arr {
Json::Array(a) => a.push(value)
_ => ()
}
}
///|
pub fn array_of(items : Array[Json]) -> Json {
let a = empty_array()
for v in items {
arr_push(a, v)
}
a
}
///|
pub fn object_of(entries : Array[(String, Json)]) -> Json {
let obj = empty_object()
for entry in entries {
let (k, v) = entry
obj_set(obj, k, v)
}
obj
}