소스 정보
- 저장소
- mratsim/tattletale
- 최근 소스 활동
- 2026년 2월 4일 22:59
- 감지된 SKILL.md 언어
- 영어
- 스타
- 40
- 포크
- 4
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/mratsim/tattletale --skill jsony명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SKILL.md 표시 중
| 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)SOC 직업 분류 기준