bijux_cli/contracts/
product_mount.rs1use std::sync::OnceLock;
4
5use serde::{Deserialize, Serialize};
6
7use super::command::Namespace;
8
9#[derive(Debug, Deserialize)]
10struct ProductRegistryDocument {
11 entries: Vec<ProductRegistryEntry>,
12}
13
14#[derive(Debug, Deserialize)]
15struct ProductRegistryEntry {
16 namespace: String,
17 runtime_binary: String,
18 control_binary: String,
19 runtime_package: String,
20 control_package: String,
21 repository: String,
22 status: String,
23}
24
25#[derive(Clone, Copy, Debug, PartialEq, Eq)]
27pub struct KnownBijuxTool {
28 pub namespace: &'static str,
30 pub runtime_binary_name: &'static str,
32 pub control_binary_name: &'static str,
34 pub runtime_package_name: &'static str,
36 pub control_package_name: &'static str,
38 pub repository_name: &'static str,
40 pub status: &'static str,
42}
43
44impl KnownBijuxTool {
45 #[must_use]
47 pub fn runtime_binary(&self) -> String {
48 self.runtime_binary_name.to_string()
49 }
50
51 #[must_use]
53 pub fn control_binary(&self) -> String {
54 self.control_binary_name.to_string()
55 }
56
57 #[must_use]
59 pub fn runtime_package(&self) -> String {
60 self.runtime_package_name.to_string()
61 }
62
63 #[must_use]
65 pub fn control_package(&self) -> String {
66 self.control_package_name.to_string()
67 }
68
69 #[must_use]
71 pub fn repository(&self) -> String {
72 self.repository_name.to_string()
73 }
74}
75
76fn leak(raw: String) -> &'static str {
77 Box::leak(raw.into_boxed_str())
78}
79
80fn load_known_bijux_tools() -> Vec<KnownBijuxTool> {
81 let raw = include_str!(concat!(
82 env!("CARGO_MANIFEST_DIR"),
83 "/contracts/official_product_namespace_registry.json"
84 ));
85 let document: ProductRegistryDocument =
86 serde_json::from_str(raw).expect("official product registry must stay valid JSON");
87
88 document
89 .entries
90 .into_iter()
91 .map(|entry| KnownBijuxTool {
92 namespace: leak(entry.namespace),
93 runtime_binary_name: leak(entry.runtime_binary),
94 control_binary_name: leak(entry.control_binary),
95 runtime_package_name: leak(entry.runtime_package),
96 control_package_name: leak(entry.control_package),
97 repository_name: leak(entry.repository),
98 status: leak(entry.status),
99 })
100 .collect()
101}
102
103fn known_bijux_tools_storage() -> &'static Vec<KnownBijuxTool> {
104 static STORAGE: OnceLock<Vec<KnownBijuxTool>> = OnceLock::new();
105 STORAGE.get_or_init(load_known_bijux_tools)
106}
107
108#[must_use]
110pub fn known_bijux_tools() -> &'static [KnownBijuxTool] {
111 known_bijux_tools_storage().as_slice()
112}
113
114fn load_known_bijux_tool_namespaces() -> Vec<&'static str> {
115 known_bijux_tools().iter().map(|tool| tool.namespace).collect()
116}
117
118#[must_use]
120pub fn known_bijux_tool_namespaces() -> &'static [&'static str] {
121 static STORAGE: OnceLock<Vec<&'static str>> = OnceLock::new();
122 STORAGE.get_or_init(load_known_bijux_tool_namespaces).as_slice()
123}
124
125#[must_use]
127pub fn official_product_namespaces() -> &'static [&'static str] {
128 known_bijux_tool_namespaces()
129}
130
131#[must_use]
133pub fn known_bijux_tool(namespace: &str) -> Option<&'static KnownBijuxTool> {
134 known_bijux_tools().iter().find(|tool| tool.namespace == namespace)
135}
136
137#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
139pub struct ProductMountMetadata {
140 pub namespace: Namespace,
142 pub runtime_binary: String,
144 pub control_binary: String,
146}