metrale_bench/
metadata.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3//! 2026-09-26: Plugin provenance: who wrote a plugin, where it came from,
4//! where to report it. Returned by [`crate::Plugin::metadata`].
5//!
6//! Every field is `&'static str` or `bool`, so a plugin's identity is fixed
7//! at compile time.
8//!
9//! Owner: bench (plugin API).
10//! Invariants:
11//! - [`PluginMetadata::third_party`] always yields `official == false`.
12
13/// 2026-09-26: Authorship and support links for one plugin.
14#[derive(Clone, Copy, Debug, PartialEq, Eq)]
15pub struct PluginMetadata {
16    /// 2026-09-26: One line: what the plugin is.
17    pub description: &'static str,
18    /// 2026-09-26: The plugin's version. First-party plugins carry the crate
19    /// version.
20    pub version: &'static str,
21    pub author: &'static str,
22    /// 2026-09-26: The author's home on the web. Empty when there is none.
23    pub author_url: &'static str,
24    pub email: &'static str,
25    pub repository: &'static str,
26    /// 2026-09-26: Documentation for this plugin specifically.
27    pub help_url: &'static str,
28    pub bug_report_url: &'static str,
29    pub license: &'static str,
30    /// 2026-09-26: True for plugins shipped inside Metrale Engine itself.
31    ///
32    /// It drives the TUI's origin badge, a trust signal. First-party plugins
33    /// get it from [`PluginMetadata::metrale`]; anything built with
34    /// [`PluginMetadata::third_party`] cannot set it.
35    pub official: bool,
36}
37
38impl PluginMetadata {
39    /// 2026-09-26: A first-party Metrale Engine plugin. Every field except the
40    /// description is the same for all of them, so this is the one place they
41    /// are written.
42    pub const fn metrale(description: &'static str) -> Self {
43        Self {
44            description,
45            version: env!("CARGO_PKG_VERSION"),
46            author: "Metrale Engine Cybersecurity",
47            author_url: "https://metrale.ai/engine",
48            email: "[email protected]",
49            repository: "https://github.com/Metrale/metrale-inference",
50            help_url: "https://book.dev.metrale.ai/benchmarks",
51            bug_report_url: "https://github.com/Metrale/metrale-inference/issues/new",
52            license: "MIT OR Apache-2.0",
53            official: true,
54        }
55    }
56
57    /// 2026-09-26: A plugin from outside the Metrale Engine tree. `official`
58    /// is forced false.
59    #[allow(clippy::too_many_arguments)]
60    pub const fn third_party(
61        description: &'static str,
62        version: &'static str,
63        author: &'static str,
64        author_url: &'static str,
65        email: &'static str,
66        repository: &'static str,
67        help_url: &'static str,
68        bug_report_url: &'static str,
69        license: &'static str,
70    ) -> Self {
71        Self {
72            description,
73            version,
74            author,
75            author_url,
76            email,
77            repository,
78            help_url,
79            bug_report_url,
80            license,
81            official: false,
82        }
83    }
84
85    /// 2026-09-26: Label/value pairs for the detail pane, skipping empty
86    /// values so a missing field does not render a blank row.
87    pub fn rows(&self) -> Vec<(&'static str, &'static str)> {
88        [
89            ("Author", self.author),
90            ("Website", self.author_url),
91            ("Contact", self.email),
92            ("Repository", self.repository),
93            ("Docs", self.help_url),
94            ("Report a bug", self.bug_report_url),
95            ("License", self.license),
96        ]
97        .into_iter()
98        .filter(|(_, v)| !v.is_empty())
99        .collect()
100    }
101}
102
103#[cfg(test)]
104mod tests {
105    use super::*;
106
107    #[test]
108    fn first_party_metadata_tracks_the_crate_version() {
109        let m = PluginMetadata::metrale("a benchmark");
110        assert_eq!(
111            m,
112            PluginMetadata {
113                description: "a benchmark",
114                version: env!("CARGO_PKG_VERSION"),
115                author: "Metrale Engine Cybersecurity",
116                author_url: "https://metrale.ai/engine",
117                email: "[email protected]",
118                repository: "https://github.com/Metrale/metrale-inference",
119                help_url: "https://book.dev.metrale.ai/benchmarks",
120                bug_report_url: "https://github.com/Metrale/metrale-inference/issues/new",
121                license: "MIT OR Apache-2.0",
122                official: true,
123            }
124        );
125    }
126
127    #[test]
128    fn third_party_cannot_claim_to_be_official() {
129        let m = PluginMetadata::third_party(
130            "community sweep",
131            "0.2.1",
132            "Someone",
133            "",
134            "",
135            "https://example.invalid/repo",
136            "",
137            "",
138            "MIT",
139        );
140        assert!(!m.official);
141    }
142
143    #[test]
144    fn empty_fields_are_not_rendered_as_blank_rows() {
145        let m = PluginMetadata::third_party("d", "1", "A", "", "", "r", "", "", "MIT");
146        assert_eq!(
147            m.rows(),
148            [("Author", "A"), ("Repository", "r"), ("License", "MIT")]
149        );
150    }
151}