git.delta.rocks / jrsonnet / refs/commits / 0ad724252f64

difftreelog

refactor replace serde-yaml with serde-saphyr for yaml parsing

oxsqnpvmYaroslav Bolyukin2026-02-07parent: #8a3d104.patch.diff
in: master

4 files changed

modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3,6 +3,19 @@
 version = 4
 
 [[package]]
+name = "ahash"
+version = "0.8.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
+dependencies = [
+ "cfg-if",
+ "getrandom",
+ "once_cell",
+ "version_check",
+ "zerocopy",
+]
+
+[[package]]
 name = "aho-corasick"
 version = "1.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -110,6 +123,12 @@
 ]
 
 [[package]]
+name = "arraydeque"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236"
+
+[[package]]
 name = "autocfg"
 version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -303,6 +322,24 @@
 checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
 
 [[package]]
+name = "encoding_rs"
+version = "0.8.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "encoding_rs_io"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1cc3c5651fb62ab8aa3103998dade57efdd028544bd300516baa31840c252a83"
+dependencies = [
+ "encoding_rs",
+]
+
+[[package]]
 name = "equivalent"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -376,9 +413,11 @@
 checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
 dependencies = [
  "cfg-if",
+ "js-sys",
  "libc",
  "r-efi",
  "wasip2",
+ "wasm-bindgen",
 ]
 
 [[package]]
@@ -434,7 +473,7 @@
  "rand",
  "random_color",
  "range-map",
- "smallvec",
+ "smallvec 1.15.1",
  "tree-sitter-highlight",
  "unicode-box-drawing",
 ]
@@ -641,8 +680,8 @@
  "regex",
  "rustc-hash 2.1.1",
  "serde",
+ "serde-saphyr",
  "serde_json",
- "serde_yaml_with_quirks",
  "sha1",
  "sha2",
  "sha3",
@@ -657,6 +696,16 @@
 ]
 
 [[package]]
+name = "js-sys"
+version = "0.3.85"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3"
+dependencies = [
+ "once_cell",
+ "wasm-bindgen",
+]
+
+[[package]]
 name = "json-structural-diff"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -772,6 +821,12 @@
 ]
 
 [[package]]
+name = "nohash-hasher"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
+
+[[package]]
 name = "num-bigint"
 version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1054,10 +1109,15 @@
 checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
 
 [[package]]
-name = "ryu"
-version = "1.0.22"
+name = "saphyr-parser-bw"
+version = "0.0.607"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984"
+checksum = "2f9bae8d059bf1ca32753cf3cdafbf5d391502de2fc2ca54510811fe9c100d90"
+dependencies = [
+ "arraydeque",
+ "smallvec 2.0.0-alpha.12",
+ "thiserror",
+]
 
 [[package]]
 name = "serde"
@@ -1070,6 +1130,27 @@
 ]
 
 [[package]]
+name = "serde-saphyr"
+version = "0.0.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc14a55107113a16346915d7e3d78acc539a923458385db89670e22cac106d7a"
+dependencies = [
+ "ahash",
+ "annotate-snippets",
+ "base64",
+ "encoding_rs_io",
+ "getrandom",
+ "nohash-hasher",
+ "num-traits",
+ "regex",
+ "saphyr-parser-bw",
+ "serde",
+ "serde_json",
+ "smallvec 2.0.0-alpha.12",
+ "zmij",
+]
+
+[[package]]
 name = "serde_core"
 version = "1.0.228"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1101,19 +1182,6 @@
  "serde",
  "serde_core",
  "zmij",
-]
-
-[[package]]
-name = "serde_yaml_with_quirks"
-version = "0.9.34"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d852180e55e824bb347a8e3cdbbca1f02513ea1fa00188f1b2a8a255ac3d6cf9"
-dependencies = [
- "indexmap",
- "itoa",
- "ryu",
- "serde",
- "unsafe-libyaml",
 ]
 
 [[package]]
@@ -1167,6 +1235,12 @@
 checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
 
 [[package]]
+name = "smallvec"
+version = "2.0.0-alpha.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef784004ca8777809dcdad6ac37629f0a97caee4c685fcea805278d81dd8b857"
+
+[[package]]
 name = "stacker"
 version = "0.1.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1337,12 +1411,6 @@
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
-
-[[package]]
-name = "unsafe-libyaml"
-version = "0.2.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
 
 [[package]]
 name = "utf8parse"
@@ -1366,6 +1434,51 @@
 ]
 
 [[package]]
+name = "wasm-bindgen"
+version = "0.2.108"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+ "rustversion",
+ "wasm-bindgen-macro",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.108"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.108"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55"
+dependencies = [
+ "bumpalo",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.108"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
 name = "windows-link"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
modifiedCargo.tomldiffbeforeafterboth
before · Cargo.toml
1[workspace]2members = ["crates/*", "bindings/jsonnet", "cmds/*", "tests", "xtask"]3default-members = ["cmds/jrsonnet"]4resolver = "2"56[workspace.package]7authors = ["Yaroslav Bolyukin <iam@lach.pw>"]8edition = "2021"9license = "MIT"10repository = "https://github.com/CertainLach/jrsonnet"11version = "0.5.0-pre97"1213[workspace.dependencies]14jrsonnet-evaluator = { path = "./crates/jrsonnet-evaluator", version = "0.5.0-pre97" }15jrsonnet-macros = { path = "./crates/jrsonnet-macros", version = "0.5.0-pre97" }16jrsonnet-parser = { path = "./crates/jrsonnet-parser", version = "0.5.0-pre97" }17jrsonnet-rowan-parser = { path = "./crates/jrsonnet-rowan-parser", version = "0.5.0-pre97" }18jrsonnet-interner = { path = "./crates/jrsonnet-interner", version = "0.5.0-pre97" }19jrsonnet-stdlib = { path = "./crates/jrsonnet-stdlib", version = "0.5.0-pre97" }20jrsonnet-cli = { path = "./crates/jrsonnet-cli", version = "0.5.0-pre97" }21jrsonnet-types = { path = "./crates/jrsonnet-types", version = "0.5.0-pre97" }22jrsonnet-gcmodule = { version = "0.4.0", path = "../gcmodule" }23# Diagnostics.24# hi-doc is my library, which handles text formatting very well, but isn't polished enough yet25# Previous implementation was based on annotate-snippets, which I don't like for many reasons.26#27# I'm against using miette, because I want to reuse data between interpreter and annotations, yet miette28#   and other libraries want to handle spans etc by itself, which is okay for compiler diagnostics, but is29#   bad for interpreter, where interpreter and parser are paired much closer.30hi-doc = "0.3.0"31annotate-snippets = "0.12.11"3233# CLI34clap = "4.5"35clap_complete = "4.5"3637# Parsing, manifestification is implemented manually everywhere38# Note on serde_yaml_with_quirks: This is a fork of serde-yaml with legacy yaml 1.1 support:39# https://github.com/dtolnay/serde-yaml/pull/22540serde = "1.0.228"41serde_json = "1.0.149"42serde_yaml_with_quirks = "0.9.34"4344# Error handling45anyhow = "1.0.101"46thiserror = "2.0.18"4748# Code formatting49dprint-core = "0.67.4"5051# Stdlib hashing functions52md5 = "0.8.0"53sha1 = "0.10.6"54sha2 = "0.10.9"55sha3 = "0.10.8"5657# Source code parsing.58# Jrsonnet has two parsers for jsonnet - one is for execution, and another is for better parsing diagnostics/lints/LSP.59# First (and fast one) is based on peg, second is based on rowan.60peg = "0.8.5"61logos = "0.16.1"62ungrammar = "1.16.1"63rowan = "0.16.1"6465mimallocator = "0.1.3"66indoc = "2.0"67insta = "1.46"68tempfile = "3.24"69pathdiff = "0.2.3"70hashbrown = "0.16.1"71static_assertions = "1.1"72rustc-hash = "2.1"73num-bigint = "0.4.6"74strsim = "0.11.1"75proc-macro2 = "1.0"76quote = "1.0"77syn = "2.0"78drop_bomb = "0.1.5"79base64 = "0.22.1"80indexmap = "2.13.0"81itertools = "0.14.0"82xshell = "0.2.7"8384lsp-server = "0.7.9"85lsp-types = "0.97.0"8687regex = "1.12"88lru = "0.16.3"8990json-structural-diff = "0.2.0"91syn-dissect-closure = "0.1.0"9293[workspace.lints.rust]94unsafe_op_in_unsafe_fn = "deny"9596# TODO: add docs everywhere97# missing_doc = "warn"9899elided_lifetimes_in_paths = "allow"100explicit_outlives_requirements = "allow"101noop_method_call = "allow"102single_use_lifetimes = "allow"103variant_size_differences = "allow"104macro_expanded_macro_exports_accessed_by_absolute_paths = "allow"105106[workspace.lints.rustdoc]107all = "warn"108109[workspace.lints.clippy]110all = { level = "warn", priority = -1 }111nursery = { level = "warn", priority = -1 }112pedantic = { level = "warn", priority = -1 }113114ptr_arg = "allow"115# Too verbose116must_use_candidate = "allow"117# A lot of functions pass around errors thrown by code118missing_errors_doc = "allow"119# A lot of pointers have interior Rc120needless_pass_by_value = "allow"121# Its fine122wildcard_imports = "allow"123enum_glob_use = "allow"124module_name_repetitions = "allow"125# TODO: fix individual issues, however this works as intended almost everywhere126cast_precision_loss = "allow"127cast_possible_wrap = "allow"128cast_possible_truncation = "allow"129cast_sign_loss = "allow"130# False positives131# https://github.com/rust-lang/rust-clippy/issues/6902132use_self = "allow"133# https://github.com/rust-lang/rust-clippy/issues/8539134iter_with_drain = "allow"135type_repetition_in_bounds = "allow"136# ci is being run with nightly, but library should work on stable137missing_const_for_fn = "allow"138# too many false-positives with .expect() calls139missing_panics_doc = "allow"140# false positive for IStr type. There is an configuration option for141# such cases, but it doesn't work:142# https://github.com/rust-lang/rust-clippy/issues/9801143mutable_key_type = "allow"144# false positives145redundant_pub_crate = "allow"146# Sometimes code is fancier without that147manual_let_else = "allow"148# Something is broken about that lint, can't be allowed for149# codegenerated-stdlib block150similar_names = "allow"151152#[profile.test]153#opt-level = 1154155[profile.release]156opt-level = 3157lto = "fat"158codegen-units = 1159debug = 0160panic = "abort"161strip = true162163[profile.releasedebug]164inherits = "release"165debug = 2166panic = "unwind"167strip = false
after · Cargo.toml
1[workspace]2members = ["crates/*", "bindings/jsonnet", "cmds/*", "tests", "xtask"]3default-members = ["cmds/jrsonnet"]4resolver = "2"56[workspace.package]7authors = ["Yaroslav Bolyukin <iam@lach.pw>"]8edition = "2021"9license = "MIT"10repository = "https://github.com/CertainLach/jrsonnet"11version = "0.5.0-pre97"1213[workspace.dependencies]14jrsonnet-evaluator = { path = "./crates/jrsonnet-evaluator", version = "0.5.0-pre97" }15jrsonnet-macros = { path = "./crates/jrsonnet-macros", version = "0.5.0-pre97" }16jrsonnet-parser = { path = "./crates/jrsonnet-parser", version = "0.5.0-pre97" }17jrsonnet-rowan-parser = { path = "./crates/jrsonnet-rowan-parser", version = "0.5.0-pre97" }18jrsonnet-interner = { path = "./crates/jrsonnet-interner", version = "0.5.0-pre97" }19jrsonnet-stdlib = { path = "./crates/jrsonnet-stdlib", version = "0.5.0-pre97" }20jrsonnet-cli = { path = "./crates/jrsonnet-cli", version = "0.5.0-pre97" }21jrsonnet-types = { path = "./crates/jrsonnet-types", version = "0.5.0-pre97" }22jrsonnet-gcmodule = { version = "0.4.0", path = "../gcmodule" }23# Diagnostics.24# hi-doc is my library, which handles text formatting very well, but isn't polished enough yet25# Previous implementation was based on annotate-snippets, which I don't like for many reasons.26#27# I'm against using miette, because I want to reuse data between interpreter and annotations, yet miette28#   and other libraries want to handle spans etc by itself, which is okay for compiler diagnostics, but is29#   bad for interpreter, where interpreter and parser are paired much closer.30hi-doc = "0.3.0"31annotate-snippets = "0.12.11"3233# CLI34clap = "4.5"35clap_complete = "4.5"3637# Parsing, manifestification is implemented manually everywhere38serde = "1.0.228"39serde_json = "1.0.149"40serde-saphyr = {version = "0.0.17", default-features = false}4142# Error handling43anyhow = "1.0.101"44thiserror = "2.0.18"4546# Code formatting47dprint-core = "0.67.4"4849# Stdlib hashing functions50md5 = "0.8.0"51sha1 = "0.10.6"52sha2 = "0.10.9"53sha3 = "0.10.8"5455# Source code parsing.56# Jrsonnet has two parsers for jsonnet - one is for execution, and another is for better parsing diagnostics/lints/LSP.57# First (and fast one) is based on peg, second is based on rowan.58peg = "0.8.5"59logos = "0.16.1"60ungrammar = "1.16.1"61rowan = "0.16.1"6263mimallocator = "0.1.3"64indoc = "2.0"65insta = "1.46"66tempfile = "3.24"67pathdiff = "0.2.3"68hashbrown = "0.16.1"69static_assertions = "1.1"70rustc-hash = "2.1"71num-bigint = "0.4.6"72strsim = "0.11.1"73proc-macro2 = "1.0"74quote = "1.0"75syn = "2.0"76drop_bomb = "0.1.5"77base64 = "0.22.1"78indexmap = "2.13.0"79itertools = "0.14.0"80xshell = "0.2.7"8182lsp-server = "0.7.9"83lsp-types = "0.97.0"8485regex = "1.12"86lru = "0.16.3"8788json-structural-diff = "0.2.0"89syn-dissect-closure = "0.1.0"9091[workspace.lints.rust]92unsafe_op_in_unsafe_fn = "deny"9394# TODO: add docs everywhere95# missing_doc = "warn"9697elided_lifetimes_in_paths = "allow"98explicit_outlives_requirements = "allow"99noop_method_call = "allow"100single_use_lifetimes = "allow"101variant_size_differences = "allow"102macro_expanded_macro_exports_accessed_by_absolute_paths = "allow"103104[workspace.lints.rustdoc]105all = "warn"106107[workspace.lints.clippy]108all = { level = "warn", priority = -1 }109nursery = { level = "warn", priority = -1 }110pedantic = { level = "warn", priority = -1 }111112ptr_arg = "allow"113# Too verbose114must_use_candidate = "allow"115# A lot of functions pass around errors thrown by code116missing_errors_doc = "allow"117# A lot of pointers have interior Rc118needless_pass_by_value = "allow"119# Its fine120wildcard_imports = "allow"121enum_glob_use = "allow"122module_name_repetitions = "allow"123# TODO: fix individual issues, however this works as intended almost everywhere124cast_precision_loss = "allow"125cast_possible_wrap = "allow"126cast_possible_truncation = "allow"127cast_sign_loss = "allow"128# False positives129# https://github.com/rust-lang/rust-clippy/issues/6902130use_self = "allow"131# https://github.com/rust-lang/rust-clippy/issues/8539132iter_with_drain = "allow"133type_repetition_in_bounds = "allow"134# ci is being run with nightly, but library should work on stable135missing_const_for_fn = "allow"136# too many false-positives with .expect() calls137missing_panics_doc = "allow"138# false positive for IStr type. There is an configuration option for139# such cases, but it doesn't work:140# https://github.com/rust-lang/rust-clippy/issues/9801141mutable_key_type = "allow"142# false positives143redundant_pub_crate = "allow"144# Sometimes code is fancier without that145manual_let_else = "allow"146# Something is broken about that lint, can't be allowed for147# codegenerated-stdlib block148similar_names = "allow"149150#[profile.test]151#opt-level = 1152153[profile.release]154opt-level = 3155lto = "fat"156codegen-units = 1157debug = 0158panic = "abort"159strip = true160161[profile.releasedebug]162inherits = "release"163debug = 2164panic = "unwind"165strip = false
modifiedcrates/jrsonnet-stdlib/Cargo.tomldiffbeforeafterboth
--- a/crates/jrsonnet-stdlib/Cargo.toml
+++ b/crates/jrsonnet-stdlib/Cargo.toml
@@ -41,8 +41,8 @@
 base64.workspace = true
 # std.parseJson
 serde_json.workspace = true
-# std.parseYaml, custom library fork is used for C++/golang compatibility
-serde_yaml_with_quirks.workspace = true
+# std.parseYaml
+serde-saphyr.workspace = true
 
 num-bigint = { workspace = true, optional = true }
 
modifiedcrates/jrsonnet-stdlib/src/parse.rsdiffbeforeafterboth
--- a/crates/jrsonnet-stdlib/src/parse.rs
+++ b/crates/jrsonnet-stdlib/src/parse.rs
@@ -1,5 +1,4 @@
 use jrsonnet_evaluator::{function::builtin, runtime_error, IStr, Result, Val};
-use serde::Deserialize;
 
 #[builtin]
 pub fn builtin_parse_json(str: IStr) -> Result<Val> {
@@ -10,17 +9,17 @@
 
 #[builtin]
 pub fn builtin_parse_yaml(str: IStr) -> Result<Val> {
-	use serde_yaml_with_quirks::DeserializingQuirks;
-	let value = serde_yaml_with_quirks::Deserializer::from_str_with_quirks(
+	let out = serde_saphyr::from_multiple_with_options::<Val>(
 		&str,
-		DeserializingQuirks { old_octals: true },
-	);
-	let mut out = vec![];
-	for item in value {
-		let val =
-			Val::deserialize(item).map_err(|e| runtime_error!("failed to parse yaml: {e}"))?;
-		out.push(val);
-	}
+		serde_saphyr::Options {
+			// Golang/C++ compat
+			legacy_octal_numbers: true,
+			// Disable budget limits - we trust the YAML input
+			budget: None,
+			..Default::default()
+		},
+	)
+	.map_err(|e| runtime_error!("failed to parse yaml: {e}"))?;
 	Ok(if out.is_empty() {
 		Val::Null
 	} else if out.len() == 1 {