一键导入
jsony
Fast JSON parsing and serialization for Nim with automatic derived hooks
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Fast JSON parsing and serialization for Nim with automatic derived hooks
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | jsony |
| description | Fast JSON parsing and serialization for Nim with automatic derived hooks |
| license | MIT |
| compatibility | opencode |
| metadata | {"audience":"developers","workflow":"data-parsing"} |
jsony is a high-performance JSON library for Nim that provides:
parseHook, dumpHook, renameHook, etc.)Use jsony when you need to:
import pkg/jsony
type MyObject = object
name: string
value: int
let json_str = """{"name": "test", "value": 42}"""
let obj = json_str.fromJson(MyObject)
let obj = MyObject(name: "test", value: 42)
let json_str = obj.toJson()
none)proc renameHook*(v: var MyObject, key: string) =
if key == "my_name":
key = "name"
proc enumHook*(strVal: string, v: var MyEnum) =
if strVal == "ACTIVE":
v = MyEnum.active
proc newHook*(v: var MyObject) =
v.value = 100 # Default value
proc postHook*(v: var MyObject) =
if v.value < 0:
raise newException(ValueError, "Value must be positive")
proc skipHook*(T: typedesc[MyObject], key: string): bool =
key == "internal_field" # Skip this field
From t_ethereum_bls_signatures.nim and t_ethereum_evm_precompiles.nim:
import pkg/jsony
type
PubkeyField = object
pubkey: array[48, byte]
DeserG1_test = object
input: PubkeyField
output: bool
# Custom parsing for byte arrays from hex strings
proc parseHook*[N: static int](src: string, pos: var int, value: var array[N, byte]) =
var str: string
parseHook(src, pos, str)
value.paddedFromHex(str, bigEndian)
# Parse test vectors
let testFile = readFile(testDir / filename)
let testData = testFile.fromJson(DeserG1_test)
# Use parsed data
let status = pubkey.deserialize_pubkey_compressed(testData.input.pubkey)
By default, jsony ignores unknown fields:
fromJson[T]() ignores extra JSON fieldsnewHook to set defaults)parseHook instead of generic parsingdistinct types automatically derive serialization-d:release for optimized parsingtry:
let obj = json_str.fromJson(MyObject)
except JsonError as e:
echo "JSON parse error: ", e.msg
From t_hash_to_curve.nim and t_ec_sage_template.nim:
type
EC_G1_hex = object
x: string
y: string
EC_G2_hex = object
x: Fp2_hex # Nested object
y: Fp2_hex
Fp2_hex = object
c0: string
c1: string
TestVector[EC: EC_ShortW_Aff] = object
P: EC # Recursive generic type
Q0, Q1: EC
msg: string
u: seq[string]
HashToCurveTest[EC: EC_ShortW_Aff] = object
L, Z, dst: string
curve: string
field: FieldDesc
vectors: seq[TestVector[EC]]
# Recursive parseHook for elliptic curve points
proc parseHook*(src: string, pos: var int, value: var EC_ShortW_Aff) =
when EC_ShortW_Aff.F is Fp:
var P: EC_G1_hex
parseHook(src, pos, P) # Recursive call
let ok = value.fromHex(P.x, P.y)
elif EC_ShortW_Aff.F is Fp2:
var P: EC_G2_hex
parseHook(src, pos, P) # Recursive call
let ok = value.fromHex(P.x.c0, P.x.c1, P.y.c0, P.y.c1)
# Generic bigint parsing
proc parseHook*(src: string, pos: var int, value: var BigInt) =
var str: string
parseHook(src, pos, str) # Parse string first
value.fromHex(str) # Then convert
# Usage with generic test vectors
let vec = loadVectors(HashToCurveTest[EC_ShortW_Aff[Fp[BLS12_381], G1]], filename)
for i in 0 ..< vec.vectors.len:
var P: EC
P.fromAffine(vec.vectors[i].P) # Nested parsing
From t_ec_sage_template.nim:
type
ScalarMulTestG2[EC: EC_ShortW_Aff, bits: static int] = object
curve, group, modulus: string
# Conditional fields based on generic parameter
when EC.F is Fp:
non_residue_twist: int
else:
non_residue_twist: array[2, int]
vectors: seq[TestVector[EC, bits]]
# Load vectors with generic type
proc loadVectors(TestType: typedesc): TestType =
const group = when TestType.EC.G == G1: "G1" else: "G2"
const filename = "tv_" & $TestType.EC.F.Name & "_scalar_mul_" & group & "_" & $TestType.bits & "bit.json"
let content = readFile(TestVectorsDir/filename)
result = content.fromJson(TestType)
# Usage
let vec = loadVectors(ScalarMulTestG2[EC_ShortW_Aff[Fp2[BLS12_381], G2], 256])
proc parseHook*(src: string, pos: var int, value: var MyGeneric[T]) =
when T is SomeNumber:
# Parse numeric type
var num: T
parseHook(src, pos, num)
value = MyGeneric[T](data: num)
elif T is string:
# Parse string type
var str: string
parseHook(src, pos, str)
value = MyGeneric[T](data: str)
proc parseHook*[EC: static typedesc](src: string, pos: var int, value: var EC) =
# Static dispatch based on EC type
when EC.G == G1:
var P: EC_G1_hex
parseHook(src, pos, P)
discard value.fromHex(P.x, P.y)
else: # EC.G == G2
var P: EC_G2_hex
parseHook(src, pos, P)
discard value.fromHex(P.x.c0, P.x.c1, P.y.c0, P.y.c1)
jsony works seamlessly with:
parseHook/dumpHook)Nim testing conventions, unittest framework, and C++ compatibility patterns
Nim bindings to libtorch for tensor operations with high-level sugar
Nim type system patterns and pitfalls
Common import patterns and pitfalls for the Tattletale Nim project
Regex functionality in Nim including std/re, std/nre wrappers around PCRE, and the pure Nim nim-regex alternative with linear-time matching guarantees
Nim to Python interoperability including nimpy for calling Python from Nim and exporting Nim to Python, nimporter for packaging Nim modules as Python packages, and cffi/ctypes for calling Nim from Python