use cosh_tools::fs::{Fs, Target};
#[tokio::main]
async fn main() {
let project = std::env::temp_dir().join("cosh-fs-edit-example");
let _ = std::fs::remove_dir_all(&project);
std::fs::create_dir_all(&project).unwrap();
let source = "\
mod math {
pub fn double(x: i32) -> i32 {
x * 2
}
}
// this comment is going away
// so is this one
fn main() {
let doubled = math::double(4);
println!(\"{doubled}\");
}
";
std::fs::write(project.join("main.rs"), source).unwrap();
let fs = Fs::new().cwd(&project);
let results = fs
.read(vec![Target {
path: "main.rs".to_string(),
line: None,
symbol: None,
line_range: None,
offset: None,
limit: None,
}])
.await;
let header = &results[0].header;
println!("read header: {header}");
let (edit_path, file_hash) = split_header(header);
println!("edit path: {edit_path}");
println!("file hash: {file_hash}");
let ops = "replace 2..4:\n\
+ pub fn triple(x: i32) -> i32 {\n\
+ x * 3\n\
+ }\n\
delete 7..8\n\
insert tail:\n\
+fn triple_main() {\n\
+ let t = math::triple(2);\n\
+ println!(\"{t}\");\n\
+}\n";
let args = serde_json::json!({
"targets": [{
"path": edit_path,
"file_hash": file_hash,
"ops": ops,
}]
});
let results = fs.edit(args).await.expect("edit should succeed");
let r = &results[0];
println!("\n== edit result ==");
println!("new header: {}", r.header);
println!("first_changed_line: {:?}", r.first_changed_line);
println!("warnings: {:?}", r.warnings);
if let Some(diff) = &r.diff {
println!("diff:\n{diff}");
}
let source_b = "mod b { pub fn x() {}\n}\n";
let source_c = "mod c { pub fn y() {}\n}\n";
std::fs::write(project.join("b.rs"), source_b).unwrap();
std::fs::write(project.join("c.rs"), source_c).unwrap();
let read_b = fs
.read(vec![Target {
path: "b.rs".to_string(),
line: None,
symbol: None,
line_range: None,
offset: None,
limit: None,
}])
.await;
let read_c = fs
.read(vec![Target {
path: "c.rs".to_string(),
line: None,
symbol: None,
line_range: None,
offset: None,
limit: None,
}])
.await;
let (path_b, hash_b) = split_header(&read_b[0].header);
let (path_c, _hash_c) = split_header(&read_c[0].header);
let args = serde_json::json!({
"targets": [
{
"path": path_b,
"file_hash": hash_b,
"ops": "insert tail:\n+// trailing comment\n",
},
{
"path": path_c,
"file_hash": "0000", "ops": "replace 1..1:\n+// never lands\n",
},
{
"path": path_c,
"file_hash": "0000",
"ops": "insert tail:\n+// never reached\n",
},
]
});
match fs.edit(args).await {
Ok(_) => println!("\n== unexpected success =="),
Err(e) => println!("\n== batch failure ==\n{e}"),
}
}
fn split_header(header: &str) -> (&str, &str) {
let body = header.strip_prefix('¶').expect("hashline prefix");
body.rsplit_once('#').expect("path#hash")
}