diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-08-02 17:32:43 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-08-02 17:32:43 +0900 |
| commit | 7e31bab9ff7209c9b6d7928a581d7a449846f42e (patch) | |
| tree | b121966a169ee74afe04d066576e862a6702bbf6 /crates/shirabe/src/json | |
| parent | ebcb4a7f013c0511dd6617686395cef17822d1e2 (diff) | |
| download | php-shirabe-7e31bab9ff7209c9b6d7928a581d7a449846f42e.tar.gz php-shirabe-7e31bab9ff7209c9b6d7928a581d7a449846f42e.tar.zst php-shirabe-7e31bab9ff7209c9b6d7928a581d7a449846f42e.zip | |
fix(json): propagate JsonFile::encode errors instead of unwrapping
PHP's JsonFile::encode throws a RuntimeException when json_encode fails; the
port swallowed that into an .unwrap() marked TODO(phase-c). Return
anyhow::Result from encode/encode_with_options and propagate at every call
site (print_table and list_repositories become Result-returning to carry it).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/json')
| -rw-r--r-- | crates/shirabe/src/json/json_file.rs | 24 | ||||
| -rw-r--r-- | crates/shirabe/src/json/json_manipulator.rs | 74 |
2 files changed, 51 insertions, 47 deletions
diff --git a/crates/shirabe/src/json/json_file.rs b/crates/shirabe/src/json/json_file.rs index cba11f01..632519a7 100644 --- a/crates/shirabe/src/json/json_file.rs +++ b/crates/shirabe/src/json/json_file.rs @@ -220,7 +220,7 @@ impl JsonFile { if self.path == "php://memory" { file_put_contents( &self.path, - Self::encode_with_options(&hash, options).as_bytes(), + Self::encode_with_options(&hash, options)?.as_bytes(), ); return Ok(()); @@ -256,7 +256,7 @@ impl JsonFile { &self.path, &format!( "{}{}", - Self::encode_with_options(&hash, options.clone()), + Self::encode_with_options(&hash, options.clone())?, if options.pretty_print { "\n" } else { "" }, ), )?; @@ -443,25 +443,23 @@ impl JsonFile { Ok(true) } - pub fn encode<T: serde::Serialize + ?Sized>(data: &T) -> String { + pub fn encode<T: serde::Serialize + ?Sized>(data: &T) -> anyhow::Result<String> { Self::encode_with_options(data, JsonEncodeOptions::default()) } pub fn encode_with_options<T: serde::Serialize + ?Sized>( data: &T, options: JsonEncodeOptions, - ) -> String { - let json = json_encode_ex(data, options.to_flags()) - .map_err(|err| RuntimeException { - message: format!("JSON encoding failed: {}", err), - code: 0, - }) - .unwrap(); // TODO(phase-c): propagating an Err. + ) -> anyhow::Result<String> { + let json = json_encode_ex(data, options.to_flags()).map_err(|err| RuntimeException { + message: format!("JSON encoding failed: {}", err), + code: 0, + })?; if options.pretty_print && options.indent != Self::INDENT_DEFAULT { // Pretty printing and not using default indentation let indent_owned = options.indent; - return Preg::replace_callback( + return Ok(Preg::replace_callback( php_regex!(r"#^ {4,}#m"), move |m: &indexmap::IndexMap< shirabe_external_packages::composer::pcre::CaptureKey, @@ -475,10 +473,10 @@ impl JsonFile { str_repeat(&indent_owned, (strlen(whole) / 4) as usize) }, &json, - ); + )); } - json + Ok(json) } /// Parses json string and returns hash. diff --git a/crates/shirabe/src/json/json_manipulator.rs b/crates/shirabe/src/json/json_manipulator.rs index 3647e846..48500de2 100644 --- a/crates/shirabe/src/json/json_manipulator.rs +++ b/crates/shirabe/src/json/json_manipulator.rs @@ -85,7 +85,7 @@ impl JsonManipulator { let m = match json_grammar::find_top_level_key( self.contents.as_bytes(), - JsonFile::encode(r#type).as_bytes(), + JsonFile::encode(r#type)?.as_bytes(), ValueKind::Json, ) { Some(m) => m, @@ -107,7 +107,7 @@ impl JsonManipulator { links = format!( "{}{}{}\"{}\"{}", &links[..key_start], - JsonFile::encode(&str_replace("\\/", "/", &existing_package)), + JsonFile::encode(&str_replace("\\/", "/", &existing_package))?, separator, constraint, &links[value_end..] @@ -133,8 +133,8 @@ impl JsonManipulator { self.newline, self.indent, self.indent, - JsonFile::encode(package), - JsonFile::encode(constraint), + JsonFile::encode(package)?, + JsonFile::encode(constraint)?, groups_1 ), "\\$", @@ -148,8 +148,8 @@ impl JsonManipulator { self.newline, self.indent, self.indent, - JsonFile::encode(package), - JsonFile::encode(constraint), + JsonFile::encode(package)?, + JsonFile::encode(constraint)?, self.newline, self.indent ); @@ -375,22 +375,28 @@ impl JsonManipulator { Some((i, e)) }) } else { - json_grammar::find_top_level_key( - self.contents.as_bytes(), - b"\"repositories\"", - ValueKind::Object, - ) - .and_then(|reps| { - let obj = self.contents[reps.value_pos..reps.value_end].to_string(); - let key = JsonFile::encode(&repository_index); - json_grammar::find_top_level_key(obj.as_bytes(), key.as_bytes(), ValueKind::Object) + { + let key = JsonFile::encode(&repository_index)?; + json_grammar::find_top_level_key( + self.contents.as_bytes(), + b"\"repositories\"", + ValueKind::Object, + ) + .and_then(|reps| { + let obj = self.contents[reps.value_pos..reps.value_end].to_string(); + json_grammar::find_top_level_key( + obj.as_bytes(), + key.as_bytes(), + ValueKind::Object, + ) .map(|inner| { ( reps.value_pos + inner.value_pos, reps.value_pos + inner.value_end, ) }) - }) + }) + } }; let (repo_pos, repo_end) = match repo_span { @@ -416,7 +422,7 @@ impl JsonManipulator { Some(u) => format!( "{}{}{}", &raw_repo[..u.value_pos], - JsonFile::encode(url), + JsonFile::encode(url)?, &raw_repo[u.value_end..] ), None => raw_repo, @@ -692,7 +698,7 @@ impl JsonManipulator { // main node content not match-able let node = match json_grammar::find_top_level_key( self.contents.as_bytes(), - JsonFile::encode(main_node).as_bytes(), + JsonFile::encode(main_node)?.as_bytes(), ValueKind::Object, ) { Some(node) => node, @@ -771,7 +777,7 @@ impl JsonManipulator { self.newline, self.indent, self.indent, - JsonFile::encode(&name_owned), + JsonFile::encode(&name_owned)?, self.format(&value_local, 1, false)?, whitespace ), @@ -787,7 +793,7 @@ impl JsonManipulator { &format!( "{{{}{}: {},{}{}{}", whitespace, - JsonFile::encode(&name_owned), + JsonFile::encode(&name_owned)?, self.format(&value_local, 1, false)?, self.newline, self.indent, @@ -812,7 +818,7 @@ impl JsonManipulator { self.newline, self.indent, self.indent, - JsonFile::encode(&name_owned), + JsonFile::encode(&name_owned)?, self.format(&value_local, 1, false)?, whitespace ); @@ -843,7 +849,7 @@ impl JsonManipulator { // no node content match-able let node = match json_grammar::find_top_level_key( self.contents.as_bytes(), - JsonFile::encode(main_node).as_bytes(), + JsonFile::encode(main_node)?.as_bytes(), ValueKind::Object, ) { Some(node) => node, @@ -1025,7 +1031,7 @@ impl JsonManipulator { // main node content not match-able let node = match json_grammar::find_top_level_key( self.contents.as_bytes(), - JsonFile::encode(main_node).as_bytes(), + JsonFile::encode(main_node)?.as_bytes(), ValueKind::Array, ) { Some(node) => node, @@ -1161,7 +1167,7 @@ impl JsonManipulator { // main node content not match-able let node = match json_grammar::find_top_level_key( self.contents.as_bytes(), - JsonFile::encode(main_node).as_bytes(), + JsonFile::encode(main_node)?.as_bytes(), ValueKind::Array, ) { Some(node) => node, @@ -1225,7 +1231,7 @@ impl JsonManipulator { // no node content match-able let node = match json_grammar::find_top_level_key( self.contents.as_bytes(), - JsonFile::encode(main_node).as_bytes(), + JsonFile::encode(main_node)?.as_bytes(), ValueKind::Array, ) { Some(node) => node, @@ -1304,7 +1310,7 @@ impl JsonManipulator { let content = self.format(&content, 0, false)?; // key exists already - let encoded_key = JsonFile::encode(key); + let encoded_key = JsonFile::encode(key)?; let key_match = if decoded.as_array().and_then(|a| a.get(key)).is_some() { json_grammar::find_top_level_key( self.contents.as_bytes(), @@ -1350,7 +1356,7 @@ impl JsonManipulator { ",{}{}{}: {}{}}}", self.newline, self.indent, - JsonFile::encode(key), + JsonFile::encode(key)?, content, self.newline ), @@ -1369,7 +1375,7 @@ impl JsonManipulator { &format!( "{}{}: {}{}}}", self.indent, - JsonFile::encode(key), + JsonFile::encode(key)?, content, self.newline ), @@ -1390,7 +1396,7 @@ impl JsonManipulator { } // key exists already - let encoded_key = JsonFile::encode(key); + let encoded_key = JsonFile::encode(key)?; let key_match = json_grammar::find_top_level_key( self.contents.as_bytes(), encoded_key.as_bytes(), @@ -1443,7 +1449,7 @@ impl JsonManipulator { } // Match the key only when its value is an empty object `{ <space> }`. - let encoded_key = JsonFile::encode(key); + let encoded_key = JsonFile::encode(key)?; let cb = self.contents.as_bytes(); let key_match = json_grammar::find_top_level_key(cb, encoded_key.as_bytes(), ValueKind::Object) @@ -1531,7 +1537,7 @@ impl JsonManipulator { elems.push(format!( "{}{}: {}", str_repeat(&self.indent, (depth + 2) as usize), - JsonFile::encode(key), + JsonFile::encode(key)?, self.format(val, depth + 1, false)? )); } @@ -1546,7 +1552,7 @@ impl JsonManipulator { )); } - Ok(JsonFile::encode(&data)) + JsonFile::encode(&data) } pub(crate) fn detect_indenting(&mut self) { @@ -1707,7 +1713,7 @@ impl ManipulatorFormatter { elems.push(format!( "{}{}: {}", str_repeat(&self.indent, (depth + 2) as usize), - JsonFile::encode(key), + JsonFile::encode(key)?, self.format(val, depth + 1, false)? )); } @@ -1722,6 +1728,6 @@ impl ManipulatorFormatter { )); } - Ok(JsonFile::encode(&data)) + JsonFile::encode(&data) } } |
