diff --git a/Cargo.lock b/Cargo.lock index c5b15f278..cd065ca2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7446,6 +7446,7 @@ dependencies = [ name = "reth-fs-util" version = "1.0.1" dependencies = [ + "serde", "serde_json", "thiserror", ] diff --git a/crates/fs-util/Cargo.toml b/crates/fs-util/Cargo.toml index aa8c322d2..907e89499 100644 --- a/crates/fs-util/Cargo.toml +++ b/crates/fs-util/Cargo.toml @@ -15,4 +15,5 @@ workspace = true # misc serde_json.workspace = true +serde.workspace = true thiserror.workspace = true diff --git a/crates/fs-util/src/lib.rs b/crates/fs-util/src/lib.rs index 8de46f561..91e60c313 100644 --- a/crates/fs-util/src/lib.rs +++ b/crates/fs-util/src/lib.rs @@ -6,10 +6,10 @@ issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] - +use serde::{de::DeserializeOwned, Serialize}; use std::{ - fs::{self, ReadDir}, - io, + fs::{self, File, ReadDir}, + io::{self, BufWriter, Write}, path::{Path, PathBuf}, }; @@ -223,6 +223,12 @@ pub fn remove_dir_all(path: impl AsRef) -> Result<()> { fs::remove_dir_all(path).map_err(|err| FsPathError::remove_dir(err, path)) } +/// Wrapper for `File::create`. +pub fn create_file(path: impl AsRef) -> Result { + let path = path.as_ref(); + File::create(path).map_err(|err| FsPathError::create_file(err, path)) +} + /// Wrapper for `std::fs::remove_file` pub fn remove_file(path: impl AsRef) -> Result<()> { let path = path.as_ref(); @@ -253,3 +259,21 @@ pub fn metadata(path: impl AsRef) -> Result { let path = path.as_ref(); fs::metadata(path).map_err(|err| FsPathError::metadata(err, path)) } + +/// Reads the JSON file and deserialize it into the provided type. +pub fn read_json_file(path: &Path) -> Result { + // read the file into a byte array first + // https://github.com/serde-rs/json/issues/160 + let bytes = read(path)?; + serde_json::from_slice(&bytes) + .map_err(|source| FsPathError::ReadJson { source, path: path.into() }) +} + +/// Writes the object as a JSON object. +pub fn write_json_file(path: &Path, obj: &T) -> Result<()> { + let file = create_file(path)?; + let mut writer = BufWriter::new(file); + serde_json::to_writer_pretty(&mut writer, obj) + .map_err(|source| FsPathError::WriteJson { source, path: path.into() })?; + writer.flush().map_err(|e| FsPathError::write(e, path)) +} diff --git a/crates/net/network/src/manager.rs b/crates/net/network/src/manager.rs index 9d68bac3c..34cd75bd3 100644 --- a/crates/net/network/src/manager.rs +++ b/crates/net/network/src/manager.rs @@ -354,11 +354,8 @@ where /// `persistent_peers_file`. pub fn write_peers_to_file(&self, persistent_peers_file: &Path) -> Result<(), FsPathError> { let known_peers = self.all_peers().collect::>(); - let known_peers = serde_json::to_string_pretty(&known_peers).map_err(|e| { - FsPathError::WriteJson { source: e, path: persistent_peers_file.to_path_buf() } - })?; persistent_peers_file.parent().map(fs::create_dir_all).transpose()?; - fs::write(persistent_peers_file, known_peers)?; + reth_fs_util::write_json_file(persistent_peers_file, &known_peers)?; Ok(()) }