ワンクリックで
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 職業分類に基づく
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
| 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)