From 1036b7e33a4360df8b99f81ef03492fee8328bd0 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Mon, 29 Jun 2026 01:30:42 +0900 Subject: refactor(json): replace seld/jsonlint with serde_json Validate JSON syntax with serde_json's parse errors in JsonFile, and detect duplicate keys in ConfigValidator with a hand-written serde visitor, dropping the now-unused JsonParser/Lexer/DuplicateKeyException ports. ParsingException is kept as the thrown error type and downcast signal. Co-Authored-By: Claude Opus 4.8 (1M context) --- crates/shirabe/src/json/json_file.rs | 59 +++++++++++++++++------------------- 1 file changed, 28 insertions(+), 31 deletions(-) (limited to 'crates/shirabe/src/json') diff --git a/crates/shirabe/src/json/json_file.rs b/crates/shirabe/src/json/json_file.rs index 0f609f2..b95732f 100644 --- a/crates/shirabe/src/json/json_file.rs +++ b/crates/shirabe/src/json/json_file.rs @@ -10,8 +10,7 @@ use crate::util::HttpDownloader; use crate::util::Silencer; use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::{CaptureKey, Preg}; -use shirabe_external_packages::seld::json_lint::JsonParser; -use shirabe_external_packages::seld::json_lint::ParsingException; +use shirabe_external_packages::seld::json_lint::{ParsingException, ParsingExceptionDetails}; use shirabe_php_shim::{ InvalidArgumentException, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE, PhpMixed, RuntimeException, UnexpectedValueException, dirname, file_exists, file_get_contents, @@ -537,39 +536,37 @@ impl JsonFile { /// @throws ParsingException /// @return bool true on success pub(crate) fn validate_syntax(json: &str, file: Option<&str>) -> anyhow::Result { - let mut parser = JsonParser::new(); - let result = parser.lint(json); - if result.is_none() { - // TODO(phase-c): Rust's &str is guaranteed as UTF-8, but PHP string is not. Change `json` - // to &[u8] and check UTF-8 validity here. - - // if (defined('JSON_ERROR_UTF8') && JSON_ERROR_UTF8 === json_last_error()) { - // if ($file === null) { - // throw new \UnexpectedValueException('The input is not UTF-8, could not parse as JSON'); - // } else { - // throw new \UnexpectedValueException('"' . $file . '" is not UTF-8, could not parse as JSON'); - // } - // } - - return Ok(true); - } + // TODO(phase-d): make json_decode() returns an error object with details. + let error = match serde_json::from_str::(json) { + Ok(_) => { + // TODO(phase-c): Rust's &str is guaranteed as UTF-8, but PHP string is not. Change `json` + // to &[u8] and check UTF-8 validity here. + + // if (defined('JSON_ERROR_UTF8') && JSON_ERROR_UTF8 === json_last_error()) { + // if ($file === null) { + // throw new \UnexpectedValueException('The input is not UTF-8, could not parse as JSON'); + // } else { + // throw new \UnexpectedValueException('"' . $file . '" is not UTF-8, could not parse as JSON'); + // } + // } + + return Ok(true); + } + Err(e) => e, + }; - let result = result.unwrap(); + let details = ParsingExceptionDetails { + line: Some(error.line() as i64), + ..Default::default() + }; Err(match file { None => ParsingException::new( - format!( - "The input does not contain valid JSON\n{}", - result.get_message() - ), - result.get_details().clone(), + format!("The input does not contain valid JSON\n{error}"), + details, ), - Some(f) => ParsingException::new( - format!( - "\"{}\" does not contain valid JSON\n{}", - f, - result.get_message() - ), - result.get_details().clone(), + Some(file) => ParsingException::new( + format!("\"{file}\" does not contain valid JSON\n{error}"), + details, ), } .into()) -- cgit v1.3.1