5个版本

0.2.2 2024年1月3日
0.2.1 2023年11月27日
0.2.0 2023年11月27日
0.1.1 2023年1月2日
0.1.0 2022年12月28日

过程宏 中排名第686

Download history 91206/week @ 2024-03-14 78240/week @ 2024-03-21 76011/week @ 2024-03-28 78110/week @ 2024-04-04 85488/week @ 2024-04-11 132485/week @ 2024-04-18 127397/week @ 2024-04-25 120543/week @ 2024-05-02 128798/week @ 2024-05-09 132797/week @ 2024-05-16 137871/week @ 2024-05-23 199497/week @ 2024-05-30 221096/week @ 2024-06-06 194355/week @ 2024-06-13 230155/week @ 2024-06-20 225684/week @ 2024-06-27

每月下载量919,542
139 个Crates中使用(直接使用5个)

Apache-2.0

14KB
192

SQL解析器推导宏

访问

此crate包含一个过程宏,可以自动推导出sqlparser crate中Visit特质的实现

#[derive(Visit, VisitMut)]
struct Foo {
    boolean: bool,
    bar: Bar,
}

#[derive(Visit, VisitMut)]
enum Bar {
    A(),
    B(String, bool),
    C { named: i32 },
}

将生成类似以下代码

impl Visit for Foo {
    fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
        self.boolean.visit(visitor)?;
        self.bar.visit(visitor)?;
        ControlFlow::Continue(())
    }
}

impl Visit for Bar {
    fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
        match self {
            Self::A() => {}
            Self::B(_1, _2) => {
                _1.visit(visitor)?;
                _2.visit(visitor)?;
            }
            Self::C { named } => {
                named.visit(visitor)?;
            }
        }
        ControlFlow::Continue(())
    }
}

某些类型可能希望在访问器上调用对应的方法

#[derive(Visit, VisitMut)]
#[visit(with = "visit_expr")]
enum Expr {
    IsNull(Box<Expr>),
    ..
}

当访问IsNull表达式时,这将导致以下访问器调用序列

visitor.pre_visit_expr(<is null expr>)
visitor.pre_visit_expr(<is null operand>)
visitor.post_visit_expr(<is null operand>)
visitor.post_visit_expr(<is null expr>)

对于某些类型,在某些上下文中仅调用特定的访问器方法是合适的。例如,并非每个ObjectName都引用一个关系。

在这些情况下,可以在我们希望调用方法的字段上使用visit属性

#[derive(Visit, VisitMut)]
#[visit(with = "visit_table_factor")]
pub enum TableFactor {
    Table {
        #[visit(with = "visit_relation")]
        name: ObjectName,
        alias: Option<TableAlias>,
    },
    ..
}

这将生成以下代码

impl Visit for TableFactor {
    fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
        visitor.pre_visit_table_factor(self)?;
        match self {
            Self::Table { name, alias } => {
                visitor.pre_visit_relation(name)?;
                alias.visit(name)?;
                visitor.post_visit_relation(name)?;
                alias.visit(visitor)?;
            }
        }
        visitor.post_visit_table_factor(self)?;
        ControlFlow::Continue(())
    }
}

请注意,同时注释类型和字段是不正确的,因为这会导致对方法的多余调用。例如

#[derive(Visit, VisitMut)]
#[visit(with = "visit_expr")]
enum Expr {
    IsNull(#[visit(with = "visit_expr")] Box<Expr>),
    ..
}

将导致以下对访问器的调用

visitor.pre_visit_expr(<is null expr>)
visitor.pre_visit_expr(<is null operand>)
visitor.pre_visit_expr(<is null operand>)
visitor.post_visit_expr(<is null operand>)
visitor.post_visit_expr(<is null operand>)
visitor.post_visit_expr(<is null expr>)

发布

此crate的发布不是自动化的。相反,根据需要手动发布

步骤

  1. 更新Cargo.toml中的版本
  2. 更新../Cargo.toml中相应的版本
  3. 通过PR提交
  4. 发布到crates.io
# update to latest checked in main branch and publish via
cargo publish 

依赖项

~290–740KB
~18K SLoC