cargo_gazelle/
rules.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10use std::collections::BTreeSet;
11
12use crate::{QuotedString, ToBazelDefinition};
13
14/// A single rule in [`rules_rust`](http://bazelbuild.github.io/rules_rust/flatten.html).
15#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
16pub enum Rule {
17    RustLibrary,
18    RustProcMacro,
19    RustTest,
20    RustDocTest,
21    RustBinary,
22    CargoBuildScript,
23    ExtractCargoLints,
24    // TODO(parkmycar): Include these rules. The tricky part is they need to
25    // get imported from the crates_universe repository that is created.
26    // Aliases,
27    // AllCrateDeps,
28}
29
30impl Rule {
31    pub fn module(&self) -> Module {
32        match self {
33            Rule::RustLibrary
34            | Rule::RustProcMacro
35            | Rule::RustTest
36            | Rule::RustDocTest
37            | Rule::RustBinary => Module::Rust,
38            Rule::CargoBuildScript | Rule::ExtractCargoLints => Module::Cargo,
39        }
40    }
41}
42
43impl ToBazelDefinition for Rule {
44    fn format(&self, writer: &mut dyn std::fmt::Write) -> Result<(), std::fmt::Error> {
45        let s = match self {
46            Rule::RustLibrary => "rust_library",
47            Rule::RustProcMacro => "rust_proc_macro",
48            Rule::RustTest => "rust_test",
49            Rule::RustDocTest => "rust_doc_test",
50            Rule::RustBinary => "rust_binary",
51            Rule::CargoBuildScript => "cargo_build_script",
52            Rule::ExtractCargoLints => "extract_cargo_lints",
53        };
54        let s = QuotedString::new(s);
55        s.format(writer)
56    }
57}
58
59/// Module within [`rules_rust`](http://bazelbuild.github.io/rules_rust) that we import [`Rule`]s
60/// from.
61#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
62pub enum Module {
63    Rust,
64    Cargo,
65}
66
67impl ToBazelDefinition for Module {
68    fn format(&self, writer: &mut dyn std::fmt::Write) -> Result<(), std::fmt::Error> {
69        let s = match self {
70            Module::Rust => "rust",
71            Module::Cargo => "cargo",
72        };
73        write!(writer, "{s}")
74    }
75}
76
77#[derive(Debug)]
78pub struct LoadStatement {
79    module: Module,
80    rules: BTreeSet<Rule>,
81}
82
83impl ToBazelDefinition for LoadStatement {
84    fn format(&self, writer: &mut dyn std::fmt::Write) -> Result<(), std::fmt::Error> {
85        write!(
86            writer,
87            "load(\"@rules_rust//{}:defs.bzl\"",
88            self.module.to_bazel_definition()
89        )?;
90        for rule in &self.rules {
91            write!(writer, ", {}", rule.to_bazel_definition())?;
92        }
93        write!(writer, ")")?;
94
95        Ok(())
96    }
97}
98
99impl From<(Module, Vec<Rule>)> for LoadStatement {
100    fn from(value: (Module, Vec<Rule>)) -> Self {
101        let rules = value.1.into_iter().collect();
102        LoadStatement {
103            module: value.0,
104            rules,
105        }
106    }
107}