Rust宏扩展库dprint-core-macros的使用:代码格式化与自动化处理工具的核心宏库

Rust宏扩展库dprint-core-macros的使用:代码格式化与自动化处理工具的核心宏库

安装

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

cargo add dprint-core-macros

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

dprint-core-macros = "0.1.0"

元数据

  • 版本: 0.1.0
  • 发布时间: 超过1年前
  • Rust版本: 2021 edition
  • 许可证: MIT
  • 大小: 1.9 KiB
  • 所有者: David Sherret (dsherret)

完整示例代码

以下是使用dprint-core-macros的完整示例:

// 导入dprint-core-macros库
use dprint_core_macros::*;

// 定义一个格式化配置结构体
#[derive(FormatConfig)]
pub struct MyConfig {
    pub line_width: u32,
    pub indent_width: u8,
    pub use_tabs: bool,
}

// 定义一个格式化规则宏
#[format_rule]
pub fn my_format_rule(context: &mut FormatContext, config: &MyConfig) {
    // 在这里实现你的格式化逻辑
    context.push_str("formatted content");
}

fn main() {
    // 创建配置实例
    let config = MyConfig {
        line_width: 80,
        indent_width: 4,
        use_tabs: false,
    };
    
    // 使用格式化规则
    let mut context = FormatContext::new();
    my_format_rule(&mut context, &config);
    
    println!("{}", context.to_string());
}

这个示例展示了如何:

  1. 使用FormatConfig派生宏定义一个配置结构体
  2. 使用format_rule属性宏定义一个格式化规则
  3. 创建配置实例并使用格式化规则处理内容

特性说明

dprint-core-macros提供的主要功能包括:

  • 配置结构体的自动派生
  • 格式化规则宏
  • 格式化上下文管理
  • 代码生成工具

该库是dprint代码格式化工具的核心宏库,主要用于简化格式化插件的开发。

扩展示例代码

以下是一个更完整的dprint-core-macros使用示例,展示了如何实现一个简单的代码格式化工具:

use dprint_core_macros::*;

// 配置结构体
#[derive(FormatConfig)]
pub struct CodeFormatterConfig {
    pub max_line_length: usize,
    pub indent_spaces: u8,
    pub newline_style: NewlineStyle,
}

#[derive(Debug, Clone)]
pub enum NewlineStyle {
    Lf,
    Crlf,
}

// 格式化规则
#[format_rule]
pub fn format_code(
    context: &mut FormatContext,
    config: &CodeFormatterConfig,
    input: &str,
) {
    // 处理换行符风格
    let newline = match config.newline_style {
        NewlineStyle::Lf => "\n",
        NewlineStyle::Crlf => "\r\n",
    };
    
    // 简单的缩进处理
    let indent = " ".repeat(config.indent_spaces as usize);
    
    // 分割输入行
    for line in input.lines() {
        let trimmed = line.trim();
        
        // 处理行长度限制
        if trimmed.len() > config.max_line_length {
            // 简单的换行处理
            let chunks = trimmed.chars()
                .collect::<Vec<_>>()
                .chunks(config.max_line_length)
                .map(|c| c.iter().collect::<String>())
                .collect::<Vec<_>>();
                
            for chunk in chunks {
                context.push_str(&indent);
                context.push_str(&chunk);
                context.push_str(newline);
            }
        } else {
            context.push_str(&indent);
            context.push_str(trimmed);
            context.push_str(newline);
        }
    }
}

fn main() {
    let config = CodeFormatterConfig {
        max_line_length: 40,
        indent_spaces: 2,
        newline_style: NewlineStyle::Lf,
    };
    
    let input = r#"
    fn main() {
        println!("This is a very long line that should be split into multiple lines because it exceeds the maximum line length.");
    }"#;
    
    let mut context = FormatContext::new();
    format_code(&mut context, &config, input);
    
    println!("Formatted code:\n{}", context.to_string());
}

这个扩展示例展示了:

  1. 更复杂的配置结构体定义
  2. 处理不同的换行符风格
  3. 实现基本的行长度限制和缩进功能
  4. 对长行进行自动分割处理

1 回复

Rust宏扩展库dprint-core-macros的使用指南

概述

dprint-core-macros是dprint代码格式化工具的核心宏库,提供了一系列用于代码格式化和自动化处理的宏。这些宏主要用于简化格式化器的开发,处理抽象语法树(AST)的转换和生成。

主要功能

  1. 提供AST节点的定义和生成宏
  2. 简化格式化规则的实现
  3. 支持代码生成和转换
  4. 为dprint生态系统提供核心宏支持

安装方法

在Cargo.toml中添加依赖:

[dependencies]
dprint-core-macros = "0.1"

核心宏介绍

ast_node!

用于定义AST节点类型:

use dprint_core_macros::ast_node;

// 定义一个函数声明AST节点
ast_node!(
    #[derive(Clone, Debug, PartialEq)]
    pub struct FunctionDeclaration {
        pub name: String,          // 函数名
        pub parameters: Vec<Parameter>,  // 参数列表
        pub body: BlockStatement,   // 函数体
    }
);

format_node!

用于定义节点的格式化规则:

use dprint_core_macros::format_node;

// 定义函数声明的格式化规则
format_node!(
    FunctionDeclaration {
        "function" name "(" parameters ")" " " body
    }
);

visit_node!

用于实现访问者模式遍历AST:

use dprint_core_macros::visit_node;

// 为函数声明实现访问者模式
visit_node!(
    impl Visitor for FunctionDeclaration {
        fn visit_children(&mut self, visitor: &mut impl Visitor) {
            visitor.visit(&mut self.name);
            for param in &mut self.parameters {
                visitor.visit(param);
            }
            visitor.visit(&mut self.body);
        }
    }
);

完整示例

下面是一个使用dprint-core-macros定义简单AST和格式化器的完整示例:

use dprint_core_macros::{ast_node, format_node, visit_node};

// 定义AST节点 - 二元表达式
ast_node!(
    #[derive(Clone, Debug, PartialEq)]
    pub struct BinaryExpression {
        pub left: Box<Expression>,  // 左表达式
        pub operator: String,       // 操作符
        pub right: Box<Expression>, // 右表达式
    }
);

// 定义AST节点 - 表达式枚举
ast_node!(
    #[derive(Clone, Debug, PartialEq)]
    pub enum Expression {
        NumberLiteral(f64),         // 数字字面量
        StringLiteral(String),      // 字符串字面量
        BinaryExpression(BinaryExpression), // 二元表达式
    }
);

// 定义二元表达式的格式化规则
format_node!(
    BinaryExpression {
        left operator " " right
    }
);

// 定义表达式的格式化规则
format_node!(
    Expression {
        match self {
            Expression::NumberLiteral(num) => num.to_string(),  // 数字直接转字符串
            Expression::StringLiteral(s) => format!("\"{}\"", s), // 字符串加引号
            Expression::BinaryExpression(expr) => expr.format(), // 二元表达式调用其format方法
        }
    }
);

// 实现二元表达式的访问者模式
visit_node!(
    impl Visitor for BinaryExpression {
        fn visit_children(&mut self, visitor: &mut impl Visitor) {
            visitor.visit(&mut self.left);
            visitor.visit(&mut self.right);
        }
    }
);

// 实现表达式的访问者模式
visit_node!(
    impl Visitor for Expression {
        fn visit_children(&mut self, visitor: &mut impl Visitor) {
            match self {
                Expression::BinaryExpression(expr) => visitor.visit(expr), // 只访问二元表达式
                _ => {}
            }
        }
    }
);

高级用法

自定义格式化配置

// 根据配置决定操作符周围的空格
format_node!(
    BinaryExpression {
        left
        if should_space_around_operator {  // 条件判断
            concat!(" ", operator, " ")    // 有空格
        } else {
            operator                       // 无空格
        }
        right
    }
);

条件格式化

// 根据参数和函数体是否为空决定格式化方式
format_node!(
    FunctionDeclaration {
        "function" name "("
        if !parameters.is_empty() {  // 参数不为空时
            parameters.join(", ")   // 用逗号分隔参数
        }
        ")" 
        if !body.statements.is_empty() {  // 函数体不为空时
            " " body                      // 添加空格和函数体
        }
    }
);

注意事项

  1. 宏生成的代码会包含一些trait实现,如FormatVisit
  2. 节点定义需要遵循一定的模式才能正确工作
  3. 格式化规则中可以使用Rust表达式,但需要返回实现ToString的类型

dprint-core-macros库是构建自定义代码格式化工具的强大基础,通过它提供的宏可以大大简化AST处理和格式化逻辑的实现。

回到顶部