1use crate::Error;
4use std::{
5 collections::HashMap,
6 fs,
7 io::{Read, Write},
8 path::{Component, Path, PathBuf},
9};
10
11pub fn replace_in_file(file_path: PathBuf, replacements: HashMap<&str, &str>) -> Result<(), Error> {
19 let mut file_content = String::new();
21 fs::File::open(&file_path)?.read_to_string(&mut file_content)?;
22 let mut modified_content = file_content;
24 for (target, replacement) in &replacements {
25 modified_content = modified_content.replace(target, replacement);
26 }
27 let mut file = fs::File::create(&file_path)?;
29 file.write_all(modified_content.as_bytes())?;
30 Ok(())
31}
32
33pub fn get_project_name_from_path<'a>(path: &'a Path, default: &'a str) -> &'a str {
40 path.file_name().and_then(|name| name.to_str()).unwrap_or(default)
41}
42
43pub fn prefix_with_current_dir_if_needed(path: PathBuf) -> PathBuf {
48 let components = &path.components().collect::<Vec<Component>>();
49 if !components.is_empty() {
50 if let Component::Normal(_) = components[0] {
52 return <Component<'_> as AsRef<Path>>::as_ref(&Component::CurDir).join(path);
53 }
54 }
55 path
56}
57
58pub fn get_relative_or_absolute_path(base: &Path, full: &Path) -> PathBuf {
65 match full.strip_prefix(base) {
66 Ok(relative) => relative.to_path_buf(),
67 Err(_) => full.to_path_buf(),
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75 use anyhow::Result;
76 use std::fs;
77
78 #[test]
79 fn test_replace_in_file() -> Result<(), Error> {
80 let temp_dir = tempfile::tempdir()?;
81 let file_path = temp_dir.path().join("file.toml");
82 let mut file = fs::File::create(temp_dir.path().join("file.toml"))?;
83 writeln!(file, "name = test, version = 5.0.0")?;
84 let mut replacements_in_cargo = HashMap::new();
85 replacements_in_cargo.insert("test", "changed_name");
86 replacements_in_cargo.insert("5.0.0", "5.0.1");
87 replace_in_file(file_path.clone(), replacements_in_cargo)?;
88 let content = fs::read_to_string(file_path).expect("Could not read file");
89 assert_eq!(content.trim(), "name = changed_name, version = 5.0.1");
90 Ok(())
91 }
92
93 #[test]
94 fn get_project_name_from_path_works() -> Result<(), Error> {
95 let path = Path::new("./path/to/project/my-parachain");
96 assert_eq!(get_project_name_from_path(path, "default_name"), "my-parachain");
97 Ok(())
98 }
99
100 #[test]
101 fn get_project_name_from_path_default_value() -> Result<(), Error> {
102 let path = Path::new("./");
103 assert_eq!(get_project_name_from_path(path, "my-contract"), "my-contract");
104 Ok(())
105 }
106
107 #[test]
108 fn prefix_with_current_dir_if_needed_works_well() {
109 let no_prefixed_path = PathBuf::from("my/path".to_string());
110 let current_dir_prefixed_path = PathBuf::from("./my/path".to_string());
111 let parent_dir_prefixed_path = PathBuf::from("../my/path".to_string());
112 let root_dir_prefixed_path = PathBuf::from("/my/path".to_string());
113 let empty_path = PathBuf::from("".to_string());
114
115 assert_eq!(
116 prefix_with_current_dir_if_needed(no_prefixed_path),
117 PathBuf::from("./my/path/".to_string())
118 );
119 assert_eq!(
120 prefix_with_current_dir_if_needed(current_dir_prefixed_path),
121 PathBuf::from("./my/path/".to_string())
122 );
123 assert_eq!(
124 prefix_with_current_dir_if_needed(parent_dir_prefixed_path),
125 PathBuf::from("../my/path/".to_string())
126 );
127 assert_eq!(
128 prefix_with_current_dir_if_needed(root_dir_prefixed_path),
129 PathBuf::from("/my/path/".to_string())
130 );
131 assert_eq!(prefix_with_current_dir_if_needed(empty_path), PathBuf::from("".to_string()));
132 }
133
134 #[test]
135 fn get_relative_or_absolute_path_works() {
136 [
137 ("/path/to/project", "/path/to/project", ""),
138 ("/path/to/project", "/path/to/src", "/path/to/src"),
139 ("/path/to/project", "/path/to/project/main.rs", "main.rs"),
140 ("/path/to/project", "/path/to/project/../main.rs", "../main.rs"),
141 ("/path/to/project", "/path/to/project/src/main.rs", "src/main.rs"),
142 ]
143 .into_iter()
144 .for_each(|(base, full, expected)| {
145 assert_eq!(
146 get_relative_or_absolute_path(Path::new(base), Path::new(full)),
147 Path::new(expected)
148 );
149 });
150 }
151}