Skip to main content

Mountain/IPC/WindServiceHandlers/FileSystem/Native/
FileCloneNative.rs

1//! Wire method `file:copy` / `file:cloneFile`. `tokio::fs::copy`
2//! preserves content but not xattrs/acls; callers that need metadata
3//! should use an OS-specific clone atom (future work).
4
5use serde_json::{Value, json};
6
7use crate::{IPC::WindServiceHandlers::Utilities::PathExtraction::Fn as extract_path_from_arg, dev_log};
8
9pub async fn Fn(Arguments:Vec<Value>) -> Result<Value, String> {
10	let Source = extract_path_from_arg(Arguments.get(0).ok_or("Missing source path")?)?;
11
12	let Target = extract_path_from_arg(Arguments.get(1).ok_or("Missing target path")?)?;
13
14	// Ensure the target parent directory exists (VS Code local history creates
15	// per-file history dirs that may not exist yet).
16	if let Some(Parent) = std::path::Path::new(&Target).parent() {
17		if !Parent.as_os_str().is_empty() {
18			tokio::fs::create_dir_all(Parent)
19				.await
20				.map_err(|E| format!("Failed to create target dir {}: {}", Parent.display(), E))?;
21		}
22	}
23
24	tokio::fs::copy(&Source, &Target)
25		.await
26		.map_err(|E| format!("Failed to clone: {} -> {} ({})", Source, Target, E))?;
27
28	// Notify Cocoon so `onDidCreateFiles` fires for the newly copied file.
29	let NewUri = format!("file://{}", Target);
30
31	dev_log!("vfs", "file:clone ok {} -> {}", Source, Target);
32
33	tokio::spawn(async move {
34		if let Err(Error) = crate::Vine::Client::SendNotification::Fn(
35			"cocoon-main".to_string(),
36			"$acceptDidCreateFiles".to_string(),
37			json!({ "files": [{ "uri": NewUri }] }),
38		)
39		.await
40		{
41			dev_log!(
42				"vfs",
43				"warn: [FileCloneNative] $acceptDidCreateFiles notify failed: {:?}",
44				Error
45			);
46		}
47	});
48
49	Ok(Value::Null)
50}