semantic-code-edit-mcp 0.1.0

MCP server for semantic code editing with tree-sitter
Documentation
use super::{LanguageCommon, LanguageName, traits::LanguageEditor};
use anyhow::{Result, anyhow};
use std::{
    io::{Read, Write},
    process::{Command, Stdio},
};

pub fn language() -> Result<LanguageCommon> {
    let language = tree_sitter_rust::LANGUAGE.into();
    let validation_query = Some(tree_sitter::Query::new(
        &language,
        include_str!("../../queries/rust/validation.scm"),
    )?);
    let editor = Box::new(RustEditor);

    Ok(LanguageCommon {
        language,
        validation_query,
        editor,
        name: LanguageName::Rust,
        file_extensions: &["rs"],
    })
}

struct RustEditor;

impl LanguageEditor for RustEditor {
    fn format_code(&self, source: &str) -> Result<String> {
        let mut child = Command::new("rustfmt")
            .args(["--emit", "stdout", "--edition", "2024"])
            .stdin(Stdio::piped())
            .stdout(Stdio::piped())
            .stderr(Stdio::piped())
            .spawn()?;

        if let Some(mut stdin) = child.stdin.take() {
            stdin.write_all(source.as_bytes())?;
            drop(stdin);
        }

        let mut stdout = String::new();
        if let Some(mut out) = child.stdout.take() {
            out.read_to_string(&mut stdout)?;
        }

        let mut stderr = String::new();
        if let Some(mut err) = child.stderr.take() {
            err.read_to_string(&mut stderr)?;
        }

        if child.wait()?.success() {
            Ok(stdout)
        } else {
            Err(anyhow!(stderr))
        }
    }
}