hedl_cli/cli/
utility.rs

1// Dweve HEDL - Hierarchical Entity Data Language
2//
3// Copyright (c) 2025 Dweve IP B.V. and individual contributors.
4//
5// SPDX-License-Identifier: Apache-2.0
6//
7// Licensed under the Apache License, Version 2.0 (the "License");
8// you may not use this file except in compliance with the License.
9// You may obtain a copy of the License in the LICENSE file at the
10// root of this repository or at: http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Utility commands for HEDL CLI.
19//!
20//! This module provides utility commands that enhance the CLI experience,
21//! such as shell completion generation.
22
23use crate::commands;
24use clap::Subcommand;
25use clap::CommandFactory;
26use clap_complete::shells::*;
27
28/// Utility commands.
29///
30/// These commands provide helpful utilities for working with the HEDL CLI,
31/// including shell completion generation and help system enhancements.
32#[derive(Subcommand)]
33pub enum UtilityCommands {
34    /// Generate shell completion scripts
35    ///
36    /// Generates shell completion scripts for various shells, enabling
37    /// tab completion for HEDL commands, options, and file names.
38    ///
39    /// Supported shells: bash, zsh, fish, powershell, elvish
40    Completion {
41        /// Shell to generate completions for (bash, zsh, fish, powershell, elvish)
42        #[arg(value_name = "SHELL")]
43        shell: String,
44
45        /// Print installation instructions instead of generating script
46        #[arg(short, long)]
47        install: bool,
48    },
49}
50
51impl UtilityCommands {
52    /// Execute the utility command.
53    ///
54    /// # Returns
55    ///
56    /// Returns `Ok(())` on success, or an error message on failure.
57    ///
58    /// # Errors
59    ///
60    /// Returns `Err` if:
61    /// - Unsupported shell is specified
62    /// - Completion generation fails
63    pub fn execute(self) -> Result<(), String> {
64        match self {
65            UtilityCommands::Completion { shell, install } => {
66                if install {
67                    println!("{}", commands::print_installation_instructions(&shell));
68                    Ok(())
69                } else {
70                    generate_completion(&shell)
71                }
72            }
73        }
74    }
75}
76
77/// Generate shell completion for the specified shell.
78///
79/// This is a helper function that creates a temporary command instance
80/// for completion generation. It needs access to the full CLI structure.
81///
82/// # Arguments
83///
84/// * `shell` - Shell name (bash, zsh, fish, powershell, elvish)
85///
86/// # Returns
87///
88/// Returns `Ok(())` on success, or an error message on failure.
89///
90/// # Errors
91///
92/// Returns `Err` if the shell is not supported.
93fn generate_completion(shell: &str) -> Result<(), String> {
94    // We need to create a temporary CLI structure for completion generation.
95    // This is a bit awkward since we're in a submodule, but we can use
96    // a trait-based approach to avoid circular dependencies.
97
98    // For now, we'll use a temporary command that matches the main CLI.
99    // This should be replaced with a better solution that uses the actual
100    // CLI command from main.rs.
101
102    use clap::Parser;
103
104    #[derive(Parser)]
105    #[command(name = "hedl")]
106    #[command(author, version, about = "HEDL - Hierarchical Entity Data Language toolkit")]
107    struct TempCli {
108        #[command(subcommand)]
109        command: super::Commands,
110    }
111
112    let mut cmd = TempCli::command();
113
114    match shell.to_lowercase().as_str() {
115        "bash" => commands::generate_completion_for_command(Bash, &mut cmd),
116        "zsh" => commands::generate_completion_for_command(Zsh, &mut cmd),
117        "fish" => commands::generate_completion_for_command(Fish, &mut cmd),
118        "powershell" | "pwsh" => commands::generate_completion_for_command(PowerShell, &mut cmd),
119        "elvish" => commands::generate_completion_for_command(Elvish, &mut cmd),
120        _ => Err(format!(
121            "Unsupported shell: '{}'. Supported shells: bash, zsh, fish, powershell, elvish",
122            shell
123        )),
124    }
125}