Skip to main content

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

1#![allow(unused_variables, dead_code, unused_imports)]
2
3//! Wire method `file:copy` / `file:cloneFile`. `tokio::fs::copy`
4//! preserves content but not xattrs/acls; callers that need metadata
5//! should use an OS-specific clone atom (future work).
6
7use serde_json::{Value, json};
8
9use crate::{IPC::WindServiceHandlers::Utilities::PathExtraction::Fn as extract_path_from_arg, dev_log};
10
11pub async fn Fn(Arguments:Vec<Value>) -> Result<Value, String> {
12	let Source = extract_path_from_arg(Arguments.get(0).ok_or("Missing source path")?)?;
13
14	let Target = extract_path_from_arg(Arguments.get(1).ok_or("Missing target path")?)?;
15
16	// Ensure the target parent directory exists (VS Code local history creates
17	// per-file history dirs that may not exist yet).
18	if let Some(Parent) = std::path::Path::new(&Target).parent() {
19		if !Parent.as_os_str().is_empty() {
20			tokio::fs::create_dir_all(Parent)
21				.await
22				.map_err(|E| format!("Failed to create target dir {}: {}", Parent.display(), E))?;
23		}
24	}
25
26	tokio::fs::copy(&Source, &Target)
27		.await
28		.map_err(|E| format!("Failed to clone: {} -> {} ({})", Source, Target, E))?;
29
30	// Notify Cocoon so `onDidCreateFiles` fires for the newly copied file.
31	let NewUri = format!("file://{}", Target);
32	dev_log!("vfs", "file:clone ok {} -> {}", Source, Target);
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}