llm_coding_tools_core/operations/
write.rs

1//! File writing operation.
2
3use crate::error::ToolResult;
4use crate::fs;
5use crate::path::PathResolver;
6
7/// Writes content to a file, creating parent directories if needed.
8///
9/// Overwrites existing files. Returns a success message with byte count.
10#[maybe_async::maybe_async]
11pub async fn write_file<R: PathResolver>(
12    resolver: &R,
13    file_path: &str,
14    content: &str,
15) -> ToolResult<String> {
16    let path = resolver.resolve(file_path)?;
17
18    // Create parent directories if they don't exist
19    if let Some(parent) = path.parent() {
20        if !parent.as_os_str().is_empty() {
21            fs::create_dir_all(parent).await?;
22        }
23    }
24
25    let bytes = content.as_bytes();
26    fs::write(&path, bytes).await?;
27
28    Ok(format!(
29        "Successfully wrote {} bytes to {}",
30        bytes.len(),
31        path.display()
32    ))
33}
34
35#[cfg(test)]
36mod tests {
37    use super::*;
38    use crate::path::AbsolutePathResolver;
39    use tempfile::TempDir;
40
41    #[maybe_async::test(feature = "blocking", async(not(feature = "blocking"), tokio::test))]
42    async fn write_creates_new_file() {
43        let temp = TempDir::new().unwrap();
44        let file_path = temp.path().join("new_file.txt");
45        let resolver = AbsolutePathResolver;
46
47        let result = write_file(&resolver, file_path.to_str().unwrap(), "hello world")
48            .await
49            .unwrap();
50
51        assert!(result.contains("11 bytes"));
52        assert_eq!(std::fs::read_to_string(&file_path).unwrap(), "hello world");
53    }
54
55    #[maybe_async::test(feature = "blocking", async(not(feature = "blocking"), tokio::test))]
56    async fn write_creates_parent_directories() {
57        let temp = TempDir::new().unwrap();
58        let file_path = temp.path().join("a/b/c/deep.txt");
59        let resolver = AbsolutePathResolver;
60
61        write_file(&resolver, file_path.to_str().unwrap(), "nested")
62            .await
63            .unwrap();
64
65        assert!(file_path.exists());
66    }
67}