aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/json/json_file.rs
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-19 21:46:01 +0900
committernsfisis <nsfisis@gmail.com>2026-05-19 21:46:08 +0900
commit5e31fa33c3b5cf726a57a063b8e7a070869250fe (patch)
tree98522466966fa7df483cad174ab5fc03db39bc09 /crates/shirabe/src/json/json_file.rs
parentc839244d8d09f3036ebfee8eef7eb6b147e593ab (diff)
downloadphp-shirabe-5e31fa33c3b5cf726a57a063b8e7a070869250fe.tar.gz
php-shirabe-5e31fa33c3b5cf726a57a063b8e7a070869250fe.tar.zst
php-shirabe-5e31fa33c3b5cf726a57a063b8e7a070869250fe.zip
fix(compile): fix more random compile errors
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/json/json_file.rs')
-rw-r--r--crates/shirabe/src/json/json_file.rs70
1 files changed, 33 insertions, 37 deletions
diff --git a/crates/shirabe/src/json/json_file.rs b/crates/shirabe/src/json/json_file.rs
index d08e207..52c3c71 100644
--- a/crates/shirabe/src/json/json_file.rs
+++ b/crates/shirabe/src/json/json_file.rs
@@ -3,7 +3,8 @@
use crate::io::io_interface;
use crate::util::silencer::Silencer;
use anyhow::Result;
-use shirabe_external_packages::composer::pcre::preg::Preg;
+use indexmap::IndexMap;
+use shirabe_external_packages::composer::pcre::preg::{CaptureKey, Preg};
use shirabe_external_packages::json_schema::validator::Validator;
use shirabe_external_packages::seld::json_lint::json_parser::JsonParser;
use shirabe_external_packages::seld::json_lint::parsing_exception::ParsingException;
@@ -28,7 +29,7 @@ pub struct JsonFile {
/// @var string
path: String,
/// @var ?HttpDownloader
- http_downloader: Option<HttpDownloader>,
+ http_downloader: Option<std::rc::Rc<std::cell::RefCell<HttpDownloader>>>,
/// @var ?IOInterface
io: Option<Box<dyn IOInterface>>,
/// @var string
@@ -67,10 +68,10 @@ impl JsonFile {
/// @throws \InvalidArgumentException
pub fn new(
path: String,
- http_downloader: Option<HttpDownloader>,
+ http_downloader: Option<std::rc::Rc<std::cell::RefCell<HttpDownloader>>>,
io: Option<Box<dyn IOInterface>>,
) -> Result<Self> {
- if http_downloader.is_none() && Preg::is_match(r"{^https?://}i", &path) {
+ if http_downloader.is_none() && Preg::is_match(r"{^https?://}i", &path).unwrap_or(false) {
return Err(InvalidArgumentException {
message: "http urls require a HttpDownloader instance to be passed".to_string(),
code: 0,
@@ -103,7 +104,11 @@ impl JsonFile {
// TODO(phase-b): use anyhow::Result<Result<T, E>> to model PHP try/catch
let json: Option<String> = match (|| -> Result<Option<String>> {
if let Some(http_downloader) = &self.http_downloader {
- Ok(Some(http_downloader.get(&self.path)?.get_body()))
+ Ok(http_downloader
+ .borrow_mut()
+ .get(&self.path, indexmap::IndexMap::new())?
+ .get_body()
+ .map(|s| s.to_string()))
} else {
if !Filesystem::is_readable(&self.path) {
return Err(RuntimeException {
@@ -120,8 +125,8 @@ impl JsonFile {
realpath_info = format!(" ({})", realpath);
}
}
- io.write_error(
- PhpMixed::String(format!("Reading {}{}", self.path, realpath_info)),
+ io.write_error3(
+ &format!("Reading {}{}", self.path, realpath_info),
true,
io_interface::NORMAL,
);
@@ -160,18 +165,22 @@ impl JsonFile {
Self::parse_json(Some(&json), Some(&self.path))
}
+ pub fn write(&self, hash: PhpMixed) -> Result<()> {
+ self.write2(
+ hash,
+ JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE,
+ )
+ }
+
/// Writes json file.
///
/// @param mixed[] $hash writes hash into json file
/// @param int $options json_encode options
/// @throws \UnexpectedValueException|\Exception
/// @return void
- pub fn write(&self, hash: PhpMixed, options: i64) -> Result<()> {
+ pub fn write2(&self, hash: PhpMixed, options: i64) -> Result<()> {
if self.path == "php://memory" {
- file_put_contents(
- &self.path,
- Self::encode(&hash, options, &self.indent).as_bytes(),
- );
+ file_put_contents(&self.path, Self::encode(&hash, options).as_bytes());
return Ok(());
}
@@ -207,7 +216,7 @@ impl JsonFile {
&self.path,
&format!(
"{}{}",
- Self::encode(&hash, options, &self.indent),
+ Self::encode(&hash, options),
if options & JSON_PRETTY_PRINT != 0 {
"\n"
} else {
@@ -362,29 +371,13 @@ impl JsonFile {
let mut validator = Validator::new();
// convert assoc arrays to objects
let data_converted = json_decode(&json_encode_ex(data, 0).unwrap_or_default(), false)?;
- validator.validate(&data_converted, &schema_data);
+ validator.check(&data_converted, &schema_data)?;
if !validator.is_valid() {
- let mut errors: Vec<String> = vec![];
- for error in validator.get_errors() {
- let property = error
- .get("property")
- .and_then(|v| v.as_string())
- .unwrap_or("");
- let message = error
- .get("message")
- .and_then(|v| v.as_string())
- .unwrap_or("");
- errors.push(format!(
- "{}{}",
- if !property.is_empty() {
- format!("{} : ", property)
- } else {
- String::new()
- },
- message,
- ));
- }
+ // TODO(phase-b): Validator::get_errors currently returns Vec<String>; original PHP
+ // exposes [{property, message}, ...]. Until shim is enriched, surface raw error
+ // strings without prop/message splitting.
+ let errors: Vec<String> = validator.get_errors();
return Err(JsonValidationException::new(
format!("\"{}\" does not match the expected JSON schema", source),
errors,
@@ -426,7 +419,7 @@ impl JsonFile {
move |m| -> String {
str_repeat(
&indent,
- (strlen(m.get(0).map(|s| s.as_str()).unwrap_or("")) / 4) as usize,
+ (strlen(m.get(&0).map(|s| s.as_str()).unwrap_or("")) / 4) as usize,
)
},
&json,
@@ -545,8 +538,11 @@ impl JsonFile {
}
pub fn detect_indenting(json: Option<&str>) -> String {
- if let Some(m) = Preg::is_match_strict_groups(r##"#^([ \t]+)"#m"##, json.unwrap_or("")) {
- return m.get(1).cloned().unwrap_or_default();
+ let mut m: IndexMap<CaptureKey, String> = IndexMap::new();
+ if Preg::is_match_strict_groups3(r##"#^([ \t]+)"#m"##, json.unwrap_or(""), Some(&mut m))
+ .unwrap_or(false)
+ {
+ return m.get(&CaptureKey::ByIndex(1)).cloned().unwrap_or_default();
}
Self::INDENT_DEFAULT.to_string()