1use std::io::ErrorKind;
7use std::path::Path;
8
9use miette::{Result, miette};
10
11pub fn read_to_string(path: &Path) -> Result<String> {
15 std::fs::read_to_string(path)
16 .map_err(|e| miette!("I/O error reading {p}: {e}", p = path.display()))
17}
18
19pub fn read_to_string_optional(path: &Path) -> Result<Option<String>> {
23 match std::fs::read_to_string(path) {
24 Ok(s) => Ok(Some(s)),
25 Err(e) if e.kind() == ErrorKind::NotFound => Ok(None),
26 Err(e) => Err(miette!("I/O error reading {p}: {e}", p = path.display())),
27 }
28}
29
30pub fn read_to_string_or_default(path: &Path) -> String {
34 std::fs::read_to_string(path).unwrap_or_default()
35}
36
37pub fn write(path: &Path, contents: impl AsRef<[u8]>) -> Result<()> {
41 std::fs::write(path, contents)
42 .map_err(|e| miette!("I/O error writing {p}: {e}", p = path.display()))
43}
44
45pub fn create_dir_all(path: &Path) -> Result<()> {
49 std::fs::create_dir_all(path)
50 .map_err(|e| miette!("I/O error creating {p}: {e}", p = path.display()))
51}
52
53pub fn read_to_string_std(path: &Path) -> std::io::Result<String> {
55 std::fs::read_to_string(path)
56}
57
58pub fn write_std(path: &Path, contents: impl AsRef<[u8]>) -> std::io::Result<()> {
60 std::fs::write(path, contents)
61}
62
63pub fn create_dir_all_std(path: &Path) -> std::io::Result<()> {
65 std::fs::create_dir_all(path)
66}
67
68pub fn write_atomic_std(path: &Path, contents: impl AsRef<[u8]>) -> std::io::Result<()> {
73 let Some(parent) = path.parent() else {
74 return std::fs::write(path, contents);
75 };
76 std::fs::create_dir_all(parent)?;
77
78 let file_name = path
79 .file_name()
80 .map(|s| s.to_string_lossy().to_string())
81 .unwrap_or_else(|| "config".to_string());
82 let tmp_name = format!(".{file_name}.tmp.{}", std::process::id());
83 let tmp_path = parent.join(tmp_name);
84
85 std::fs::write(&tmp_path, contents)?;
86
87 #[cfg(windows)]
88 {
89 let _ = std::fs::remove_file(path);
90 }
91
92 let r = std::fs::rename(&tmp_path, path);
93 if r.is_err() {
94 let _ = std::fs::remove_file(&tmp_path);
95 }
96 r
97}