84 lines
2.7 KiB
Nix
84 lines
2.7 KiB
Nix
# Provides json2nix command for converting JSON to Nix attribute set syntax
|
|
# Usage: wl-paste | json2nix | wl-copy
|
|
# json2nix < settings.json
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
let
|
|
cfg = config.json2nix;
|
|
|
|
json2nixScript = pkgs.writeScriptBin "json2nix" ''
|
|
#!${pkgs.python3}/bin/python3
|
|
"""Convert JSON to Nix attribute set syntax.
|
|
|
|
Usage: wl-paste | json2nix | wl-copy
|
|
json2nix < settings.json
|
|
"""
|
|
import json
|
|
import sys
|
|
|
|
def to_nix(obj, indent=0):
|
|
"""Convert a Python object (from JSON) to Nix syntax."""
|
|
spaces = " " * indent
|
|
|
|
if obj is None:
|
|
return "null"
|
|
elif isinstance(obj, bool):
|
|
return "true" if obj else "false"
|
|
elif isinstance(obj, int):
|
|
return str(obj)
|
|
elif isinstance(obj, float):
|
|
# Ensure floats stay as floats (e.g., 1.0 not 1)
|
|
s = str(obj)
|
|
if '.' not in s and 'e' not in s.lower():
|
|
s += ".0"
|
|
return s
|
|
elif isinstance(obj, str):
|
|
# Escape special characters for Nix strings
|
|
escaped = obj.replace("\\", "\\\\")
|
|
escaped = escaped.replace('"', '\\"')
|
|
escaped = escaped.replace("\n", "\\n")
|
|
escaped = escaped.replace("\r", "\\r")
|
|
escaped = escaped.replace("\t", "\\t")
|
|
return f'"{escaped}"'
|
|
elif isinstance(obj, list):
|
|
if not obj:
|
|
return "[ ]"
|
|
items = []
|
|
for item in obj:
|
|
items.append(f"{spaces} {to_nix(item, indent + 1)}")
|
|
return "[\n" + "\n".join(items) + f"\n{spaces}]"
|
|
elif isinstance(obj, dict):
|
|
if not obj:
|
|
return "{ }"
|
|
items = []
|
|
for key, value in obj.items():
|
|
# Quote keys that aren't valid Nix identifiers
|
|
if not key.isidentifier() or key in ['if', 'then', 'else', 'let', 'in', 'with', 'rec', 'inherit', 'or', 'and']:
|
|
nix_key = f'"{key}"'
|
|
else:
|
|
nix_key = key
|
|
nix_value = to_nix(value, indent + 1)
|
|
items.append(f"{spaces} {nix_key} = {nix_value};")
|
|
return "{\n" + "\n".join(items) + f"\n{spaces}}}"
|
|
|
|
try:
|
|
data = json.load(sys.stdin)
|
|
print(to_nix(data))
|
|
except json.JSONDecodeError as e:
|
|
print(f"Error: Invalid JSON - {e}", file=sys.stderr)
|
|
sys.exit(1)
|
|
except Exception as e:
|
|
print(f"Error: {e}", file=sys.stderr)
|
|
sys.exit(1)
|
|
'';
|
|
in
|
|
{
|
|
options.json2nix = {
|
|
enable = lib.mkEnableOption "json2nix command for converting JSON to Nix syntax";
|
|
};
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
home.packages = [ json2nixScript ];
|
|
};
|
|
}
|