Skip to main content

bijux_cli/features/install/
metadata.rs

1#![forbid(unsafe_code)]
2//! Install metadata and package-channel strategy contracts.
3
4use crate::contracts::{known_bijux_tool, known_bijux_tools};
5
6/// Canonical executable name.
7pub const CANONICAL_EXECUTABLE: &str = "bijux";
8
9/// Installation ecosystem.
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum Ecosystem {
12    /// Cargo package installation.
13    Cargo,
14    /// Python package installation.
15    Pip,
16}
17
18/// Install strategy contract for a package channel.
19#[derive(Debug, Clone, PartialEq, Eq)]
20pub struct InstallStrategy {
21    /// Ecosystem used for install.
22    pub ecosystem: Ecosystem,
23    /// Package name to install.
24    pub package_name: String,
25    /// Executable exposed on PATH.
26    pub executable_name: String,
27}
28
29/// Canonical install target after alias resolution.
30#[derive(Debug, Clone, PartialEq, Eq)]
31pub struct InstallTarget {
32    /// Canonical short target name accepted by `bijux install`.
33    pub target_name: String,
34    /// Strategy to install the requested target.
35    pub strategy: InstallStrategy,
36}
37
38/// Decide canonical crate naming strategy.
39#[must_use]
40pub fn canonical_crate_name() -> &'static str {
41    "bijux-cli"
42}
43
44fn cargo_install_strategy_for(package_name: &str, executable_name: &str) -> InstallStrategy {
45    InstallStrategy {
46        ecosystem: Ecosystem::Cargo,
47        package_name: package_name.to_string(),
48        executable_name: executable_name.to_string(),
49    }
50}
51
52fn dev_cli_install_strategy() -> InstallStrategy {
53    cargo_install_strategy_for("bijux-dev-cli", "bijux-dev-cli")
54}
55
56/// Build cargo install strategy for the documented public package.
57#[must_use]
58pub fn cargo_install_strategy() -> InstallStrategy {
59    cargo_install_strategy_for("bijux-cli", CANONICAL_EXECUTABLE)
60}
61
62/// Build pip install strategy for the documented public package.
63#[must_use]
64pub fn pip_install_strategy() -> InstallStrategy {
65    InstallStrategy {
66        ecosystem: Ecosystem::Pip,
67        package_name: "bijux-cli".to_string(),
68        executable_name: CANONICAL_EXECUTABLE.to_string(),
69    }
70}
71
72/// Resolve an install target alias into its canonical package strategy.
73#[must_use]
74pub fn resolve_install_target(raw_target: &str) -> Option<InstallTarget> {
75    let normalized = raw_target.trim().to_ascii_lowercase();
76    if normalized.is_empty() {
77        return None;
78    }
79
80    match normalized.as_str() {
81        "cli" | "bijux-cli" => {
82            return Some(InstallTarget {
83                target_name: "cli".to_string(),
84                strategy: cargo_install_strategy(),
85            });
86        }
87        "dev-cli" | "bijux-dev-cli" => {
88            return Some(InstallTarget {
89                target_name: "dev-cli".to_string(),
90                strategy: dev_cli_install_strategy(),
91            });
92        }
93        _ => {}
94    }
95
96    if let Some(namespace) = normalized.strip_prefix("dev-") {
97        let tool = known_bijux_tool(namespace)?;
98        return Some(InstallTarget {
99            target_name: format!("dev-{namespace}"),
100            strategy: cargo_install_strategy_for(
101                tool.control_package_name,
102                tool.control_binary_name,
103            ),
104        });
105    }
106
107    if let Some(tool) = known_bijux_tool(&normalized) {
108        return Some(InstallTarget {
109            target_name: tool.namespace.to_string(),
110            strategy: cargo_install_strategy_for(
111                tool.runtime_package_name,
112                tool.runtime_binary_name,
113            ),
114        });
115    }
116
117    known_bijux_tools().iter().find_map(|tool| {
118        if normalized == tool.runtime_binary_name || normalized == tool.runtime_package_name {
119            return Some(InstallTarget {
120                target_name: tool.namespace.to_string(),
121                strategy: cargo_install_strategy_for(
122                    tool.runtime_package_name,
123                    tool.runtime_binary_name,
124                ),
125            });
126        }
127        if normalized == tool.control_binary_name || normalized == tool.control_package_name {
128            return Some(InstallTarget {
129                target_name: format!("dev-{}", tool.namespace),
130                strategy: cargo_install_strategy_for(
131                    tool.control_package_name,
132                    tool.control_binary_name,
133                ),
134            });
135        }
136        None
137    })
138}
139
140/// List canonical short aliases supported by `bijux install`.
141#[must_use]
142pub fn install_target_aliases() -> Vec<String> {
143    let mut aliases = vec!["cli".to_string(), "dev-cli".to_string()];
144    for tool in known_bijux_tools() {
145        aliases.push(tool.namespace.to_string());
146        aliases.push(format!("dev-{}", tool.namespace));
147    }
148    aliases
149}