diff --git a/crates/builtin/build.rs b/crates/builtin/build.rs index 0e84360..6e44218 100644 --- a/crates/builtin/build.rs +++ b/crates/builtin/build.rs @@ -114,34 +114,33 @@ fn dump_builtin_infos() -> Vec { .arg("__dump-language") .json::() { - return std::iter::empty() - .chain( - lang.builtins - .into_iter() - .map(|(name, builtin)| BuiltinInfo { - name, - kind: "Function".into(), - doc: builtin.doc, - args: builtin.args, - impure_only: false, - experimental_feature: builtin.experimental_feature, - }), - ) - .chain(lang.constants.into_iter().map(|(name, constant)| { - let kind = if constant.type_.eq_ignore_ascii_case("set") { + let builtins = match lang { + DumpLanguage::V2 { builtins } => builtins, + DumpLanguage::V1 { + mut builtins, + constants, + } => { + builtins.extend(constants); + builtins + } + }; + return builtins + .into_iter() + .map(|(name, builtin)| BuiltinInfo { + name, + kind: if !builtin.args.is_empty() { + "Function" + } else if builtin.type_.is_some_and(|s| s.eq_ignore_ascii_case("set")) { "Attrset" } else { "Const" - }; - BuiltinInfo { - name, - kind: kind.into(), - doc: constant.doc, - args: Vec::new(), - impure_only: constant.impure_only, - experimental_feature: None, } - })) + .into(), + doc: builtin.doc, + args: builtin.args, + impure_only: builtin.impure_only, + experimental_feature: builtin.experimental_feature, + }) .collect(); } @@ -200,19 +199,18 @@ struct BuiltinInfo { } #[derive(Debug, Deserialize)] -struct DumpLanguage { - builtins: DumpBuiltins, - constants: BTreeMap, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "kebab-case")] -struct DumpConstant { - doc: String, - impure_only: bool, - // TODO - #[serde(rename = "type")] - type_: String, +#[serde(untagged)] +enum DumpLanguage { + // Nix < 2.24 + V1 { + builtins: DumpBuiltins, + constants: DumpBuiltins, + }, + // Nix >= 2.24 + V2 { + #[serde(flatten)] + builtins: BTreeMap, + }, } // Keep names sorted. @@ -221,8 +219,13 @@ type DumpBuiltins = BTreeMap; #[derive(Debug, Deserialize)] #[serde(rename_all = "kebab-case")] struct DumpBuiltin { + #[serde(default)] args: Vec, doc: String, #[serde(default)] experimental_feature: Option, + #[serde(default)] + impure_only: bool, + #[serde(rename = "type")] + type_: Option, }