Rust宏处理服务器库ra_ap_proc_macro_srv的使用:支持过程宏扩展与编译时代码生成的Rust插件

Rust宏处理服务器库ra_ap_proc_macro_srv的使用:支持过程宏扩展与编译时代码生成的Rust插件

安装

在项目目录中运行以下Cargo命令:

cargo add ra_ap_proc_macro_srv

或者在Cargo.toml中添加以下行:

ra_ap_proc_macro_srv = "0.0.296"

示例代码

以下是一个使用ra_ap_proc_macro_srv库的完整示例,展示了如何创建和使用过程宏服务器:

use ra_ap_proc_macro_srv::ProcMacroSrv;
use std::io::{self, BufRead, BufReader, Write};
use std::process::{ChildStdin, ChildStdout};

fn main() -> io::Result<()> {
    // 创建过程宏服务器
    let mut srv = ProcMacroSrv::default();
    
    // 获取IO流
    let stdin = io::stdin();
    let stdout = io::stdout();
    
    // 创建缓冲读写器
    let mut reader = BufReader::new(stdin.lock());
    let mut writer = stdout.lock();
    
    // 处理输入输出
    loop {
        let mut line = String::new();
        reader.read_line(&mut line)?;
        
        // 处理宏请求
        let response = srv.process(&line);
        
        // 写回响应
        writeln!(writer, "{}", response)?;
        writer.flush()?;
    }
}

完整示例Demo

这是一个更完整的示例,展示了如何设置一个基本的过程宏服务器并处理宏扩展请求:

use ra_ap_proc_macro_srv::{ExpansionResult, ProcMacroSrv};
use std::io::{self, BufRead, BufReader, Write};
use std::path::PathBuf;
use std::sync::Arc;

// 自定义宏服务器实现
struct MyMacroServer;

impl ProcMacroSrv for MyMacroServer {
    fn expand(
        &self,
        macro_name: &str,
        macro_body: &str,
        attributes: Option<&str>,
    ) -> ExpansionResult {
        // 在这里实现自定义的宏扩展逻辑
        match macro_name {
            "my_macro" => ExpansionResult::Str("/* expanded macro content */".to_string()),
            _ => ExpansionResult::Err("Unknown macro".to_string()),
        }
    }
}

fn main() -> io::Result<()> {
    // 创建自定义宏服务器
    let srv = Arc::new(MyMacroServer);
    
    // 设置工作目录
    let work_dir = PathBuf::from(".");
    
    // 创建标准IO的缓冲读写器
    let stdin = io::stdin();
    let stdout = io::stdout();
    let mut reader = BufReader::new(stdin.lock());
    let mut writer = stdout.lock();
    
    // 处理请求循环
    loop {
        let mut request = String::new();
        reader.read_line(&mut request)?;
        
        // 处理请求并获取响应
        let response = srv.process_request(&request, &work_dir);
        
        // 写回响应
        writeln!(writer, "{}", response)?;
        writer.flush()?;
    }
}

文档

更多详细信息和API参考,请查看官方文档。

仓库

源代码和贡献指南可在GitHub仓库找到。

许可证

这个库采用MIT或Apache-2.0双许可证发布。


1 回复

Rust宏处理服务器库 ra_ap_proc_macro_srv 使用指南

ra_ap_proc_macro_srv 是一个用于处理 Rust 过程宏的服务器库,它支持过程宏扩展和编译时代码生成,是 Rust 分析器 (rust-analyzer) 的一部分。

主要功能

  • 提供过程宏扩展服务
  • 支持编译时代码生成
  • 可作为独立进程运行
  • 与 IDE 工具集成

安装方法

Cargo.toml 中添加依赖:

[dependencies]
ra_ap_proc_macro_srv = "0.0"

基本使用方法

1. 创建宏服务器

use ra_ap_proc_macro_srv::ProcMacroSrv;

fn main() {
    let srv = ProcMacroSrv::default();
    // 现在可以使用srv处理宏请求
}

2. 处理宏扩展请求

use ra_ap_proc_macro_srv::{ProcMacroSrv, ExpandMacro};

let srv = ProcMacroSrv::default();
let request = ExpandMacro {
    macro_body: "println!(\"Hello, world!\")".to_string(),
    macro_name: "println".to_string(),
    attributes: None,
    lib: "proc_macro".to_string(),
    env: vec![],
};

let response = srv.expand(&request);
println!("Expanded code: {:?}", response);

3. 作为独立服务器运行

use ra_ap_proc_macro_srv::cli::run_server;

fn main() {
    run_server().expect("Failed to run proc macro server");
}

高级用法

自定义宏处理器

use ra_ap_proc_macro_srv::{ProcMacroSrv, ProcMacroKind, ProcMacro};

struct MyMacro;

impl ProcMacro for MyMacro {
    fn expand(&self, input: &str) -> Result<String, String> {
        Ok(format!("// Expanded by MyMacro\n{}", input))
    }
}

fn main() {
    let mut srv = ProcMacroSrv::default();
    srv.add_macro(
        "my_macro".to_string(),
        ProcMacroKind::Bang,
        Box::new(MyMacro),
    );
    
    // 现在可以使用my_macro!进行扩展
}

与 rust-analyzer 集成

use ra_ap_proc_macro_srv::server::ProcMacroServer;

fn main() {
    let server = ProcMacroServer::new();
    server.run();
}

实际应用示例

1. 创建自定义派生宏

use ra_ap_proc_macro_srv::{ProcMacroSrv, ProcMacroKind, ProcMacro};

#[derive(Debug)]
struct JsonDerive;

impl ProcMacro for JsonDerive {
    fn expand(&self, input: &str) -> Result<String, String> {
        // 简单的JSON派生宏实现
        Ok(format!(
            "impl Json for {} {{
                fn to_json(&self) -> String {{
                    serde_json::to_string(self).unwrap()
                }}
            }}",
            input
        ))
    }
}

fn main() {
    let mut srv = ProcMacroSrv::default();
    srv.add_macro(
        "Json".to_string(),
        ProcMacroKind::Derive,
        Box::new(JsonDerive),
    );
}

2. 属性宏示例

use ra_ap_proc_macro_srv::{ProcMacroSrv, ProcMacroKind, ProcMacro};

struct RouteMacro;

impl ProcMacro for RouteMacro {
    fn expand(&self, input: &str) -> Result<String, String> {
        // 简单的路由属性宏
        Ok(format!(
            "#[allow(unused)]
            fn generated_route() {{
                println!(\"Route registered for: {}\");
                {}
            }}",
            input, input
        ))
    }
}

fn main() {
    let mut srv = ProcMacroSrv::default();
    srv.add_macro(
        "route".to_string(),
        ProcMacroKind::Attr,
        Box::new(RouteMacro),
    );
}

完整示例

下面是一个完整的自定义派生宏示例,展示了如何创建一个简单的Debug派生宏:

use ra_ap_proc_macro_srv::{ProcMacroSrv, ProcMacroKind, ProcMacro};

// 自定义Debug派生宏实现
#[derive(Debug)]
struct SimpleDebugDerive;

impl ProcMacro for SimpleDebugDerive {
    fn expand(&self, input: &str) -> Result<String, String> {
        // 解析输入结构体名称
        let struct_name = input.split_whitespace()
            .next()
            .unwrap_or("MyStruct");
            
        // 生成Debug实现
        Ok(format!(
            "impl std::fmt::Debug for {} {{
                fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {{
                    write!(f, \"{} {{ }}\")
                }}
            }}",
            struct_name, struct_name
        ))
    }
}

fn main() {
    // 创建宏服务器
    let mut srv = ProcMacroSrv::default();
    
    // 添加自定义派生宏
    srv.add_macro(
        "SimpleDebug".to_string(),
        ProcMacroKind::Derive,
        Box::new(SimpleDebugDerive),
    );
    
    // 模拟宏扩展请求
    let request = ExpandMacro {
        macro_body: "struct Point { x: i32, y: i32 }".to_string(),
        macro_name: "SimpleDebug".to_string(),
        attributes: None,
        lib: "proc_macro".to_string(),
        env: vec![],
    };
    
    let response = srv.expand(&request);
    println!("Generated code:\n{}", response.unwrap());
}

注意事项

  1. ra_ap_proc_macro_srv 主要用于开发工具链,不是常规应用程序开发的首选
  2. 在生产环境中使用前应充分测试宏扩展行为
  3. 性能敏感场景可能需要自定义优化
  4. 与 rustc 版本兼容性需要注意

这个库特别适合开发需要深度集成 Rust 宏系统的工具,如 IDE 插件、自定义代码生成器等。

回到顶部