Skip to main content

oak_pretty_print/rules/
mod.rs

1use crate::{Document, FormatContext, FormatResult};
2use alloc::{boxed::Box, vec::Vec};
3use oak_core::{
4    errors::OakError,
5    language::Language,
6    tree::{RedLeaf, RedNode},
7};
8
9/// 格式化规则 trait
10pub trait FormatRule<L: Language> {
11    /// 规则名称
12    fn name(&self) -> &str;
13
14    /// 规则优先级(数字越大优先级越高)
15    fn priority(&self) -> u8 {
16        0
17    }
18
19    /// 检查规则是否适用于给定节点
20    fn applies_to_node(&self, _node: &RedNode<L>) -> bool {
21        false
22    }
23
24    /// 检查规则是否适用于给定 Token
25    fn applies_to_token(&self, _token: &RedLeaf<L>) -> bool {
26        false
27    }
28
29    /// 应用格式化规则到节点,返回可选的 Document
30    fn apply_node<'a>(&self, node: &RedNode<L>, context: &FormatContext<L>, source: &'a str, format_children: &dyn Fn(&RedNode<L>) -> FormatResult<Document<'a>>) -> FormatResult<Option<Document<'a>>>;
31
32    /// 应用格式化规则到 Token,返回可选的 Document
33    fn apply_token<'a>(&self, token: &RedLeaf<L>, context: &FormatContext<L>, source: &'a str) -> FormatResult<Option<Document<'a>>>;
34
35    /// 规则是否与其他规则冲突
36    fn conflicts_with(&self, _other: &dyn FormatRule<L>) -> bool {
37        false
38    }
39}
40
41/// 规则集合
42pub struct RuleSet<L: Language> {
43    rules: Vec<Box<dyn FormatRule<L>>>,
44}
45
46impl<L: Language> Default for RuleSet<L> {
47    fn default() -> Self {
48        Self { rules: Vec::new() }
49    }
50}
51
52impl<L: Language> RuleSet<L> {
53    /// 创建新的规则集合
54    pub fn new() -> Self {
55        Self::default()
56    }
57
58    /// 添加规则
59    pub fn add_rule(&mut self, rule: Box<dyn FormatRule<L>>) -> FormatResult<()> {
60        // 检查规则冲突
61        for existing_rule in &self.rules {
62            if rule.conflicts_with(existing_rule.as_ref()) || existing_rule.conflicts_with(rule.as_ref()) {
63                return Err(OakError::format_error(format!("Rule conflict between '{}' and '{}'", existing_rule.name(), rule.name())));
64            }
65        }
66
67        self.rules.push(rule);
68
69        // 按优先级排序
70        self.rules.sort_by(|a, b| b.priority().cmp(&a.priority()));
71
72        Ok(())
73    }
74
75    /// 批量添加规则
76    pub fn add_rules(&mut self, rules: Vec<Box<dyn FormatRule<L>>>) -> FormatResult<()> {
77        for rule in rules {
78            self.add_rule(rule)?;
79        }
80        Ok(())
81    }
82
83    /// 获取适用于节点的规则
84    pub fn applicable_rules_for_node<'a>(&'a self, node: &'a RedNode<L>) -> impl Iterator<Item = &'a dyn FormatRule<L>> + 'a {
85        self.rules.iter().filter(move |rule| rule.applies_to_node(node)).map(|rule| rule.as_ref())
86    }
87
88    /// 获取适用于 Token 的规则
89    pub fn applicable_rules_for_token<'a>(&'a self, token: &'a RedLeaf<L>) -> impl Iterator<Item = &'a dyn FormatRule<L>> + 'a {
90        self.rules.iter().filter(move |rule| rule.applies_to_token(token)).map(|rule| rule.as_ref())
91    }
92
93    /// 应用所有适用的节点规则,返回第一个成功的 Document
94    pub fn apply_node_rules<'a>(&self, node: &RedNode<L>, context: &FormatContext<L>, source: &'a str, format_children: &dyn Fn(&RedNode<L>) -> FormatResult<Document<'a>>) -> FormatResult<Option<Document<'a>>> {
95        for rule in self.applicable_rules_for_node(node) {
96            if let Some(doc) = rule.apply_node(node, context, source, format_children)? {
97                return Ok(Some(doc));
98            }
99        }
100        Ok(None)
101    }
102
103    /// 应用所有适用的 Token 规则,返回第一个成功的 Document
104    pub fn apply_token_rules<'a>(&self, token: &RedLeaf<L>, context: &FormatContext<L>, source: &'a str) -> FormatResult<Option<Document<'a>>> {
105        for rule in self.applicable_rules_for_token(token) {
106            if let Some(doc) = rule.apply_token(token, context, source)? {
107                return Ok(Some(doc));
108            }
109        }
110        Ok(None)
111    }
112}