hedl_cli/cli/
core.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//! Core HEDL commands for validation, formatting, linting, and inspection.
19//!
20//! This module contains the fundamental HEDL CLI commands that operate on
21//! individual HEDL files for validation, formatting, and analysis.
22
23use crate::commands;
24use clap::Subcommand;
25
26/// Core HEDL commands.
27///
28/// These commands provide the essential functionality for working with HEDL files:
29/// validation, formatting, linting, inspection, and statistics.
30///
31/// # Commands
32///
33/// - **Validate**: Check HEDL syntax and semantic correctness
34/// - **Format**: Convert to canonical form with optional optimizations
35/// - **Lint**: Check for best practices and style issues
36/// - **Inspect**: Visualize internal structure
37/// - **Stats**: Analyze size and token efficiency
38#[derive(Subcommand)]
39pub enum CoreCommands {
40    /// Validate a HEDL file
41    ///
42    /// Checks the syntax and semantic correctness of a HEDL file. In strict mode,
43    /// all references must resolve to existing entities.
44    Validate {
45        /// Input file path
46        #[arg(value_name = "FILE")]
47        file: String,
48
49        /// Strict mode (fail on any error)
50        #[arg(short, long)]
51        strict: bool,
52    },
53
54    /// Format a HEDL file to canonical form
55    ///
56    /// Reformats a HEDL file to its canonical representation. Supports various
57    /// formatting options including ditto optimization and automatic count hints.
58    Format {
59        /// Input file path
60        #[arg(value_name = "FILE")]
61        file: String,
62
63        /// Output file path (defaults to stdout)
64        #[arg(short, long)]
65        output: Option<String>,
66
67        /// Check only (exit 1 if not canonical)
68        #[arg(short, long)]
69        check: bool,
70
71        /// Use ditto optimization
72        #[arg(long, default_value = "true")]
73        ditto: bool,
74
75        /// Automatically add count hints to all matrix lists
76        #[arg(long)]
77        with_counts: bool,
78    },
79
80    /// Lint a HEDL file for best practices
81    ///
82    /// Analyzes a HEDL file for style issues, best practices violations, and
83    /// potential problems. Can output results in text or JSON format.
84    Lint {
85        /// Input file path
86        #[arg(value_name = "FILE")]
87        file: String,
88
89        /// Output format (text, json)
90        #[arg(short, long, default_value = "text")]
91        format: String,
92
93        /// Treat warnings as errors
94        #[arg(short = 'W', long)]
95        warn_error: bool,
96    },
97
98    /// Print parsed structure (debug)
99    ///
100    /// Displays the internal structure of a HEDL file as a tree, useful for
101    /// debugging and understanding how HEDL parses the file.
102    Inspect {
103        /// Input file path
104        #[arg(value_name = "FILE")]
105        file: String,
106
107        /// Show detailed internal structure
108        #[arg(short, long)]
109        verbose: bool,
110    },
111
112    /// Show size/token savings vs other formats
113    ///
114    /// Analyzes a HEDL file and compares its size and token count against
115    /// equivalent representations in JSON, YAML, XML, CSV, and Parquet.
116    Stats {
117        /// Input HEDL file
118        #[arg(value_name = "FILE")]
119        file: String,
120
121        /// Show estimated token counts for LLM context
122        #[arg(short, long)]
123        tokens: bool,
124    },
125}
126
127impl CoreCommands {
128    /// Execute the core command.
129    ///
130    /// # Returns
131    ///
132    /// Returns `Ok(())` on success, or an error message on failure.
133    ///
134    /// # Errors
135    ///
136    /// Returns `Err` if the command execution fails.
137    pub fn execute(self) -> Result<(), crate::error::CliError> {
138        match self {
139            CoreCommands::Validate { file, strict } => commands::validate(&file, strict),
140            CoreCommands::Format {
141                file,
142                output,
143                check,
144                ditto,
145                with_counts,
146            } => commands::format(&file, output.as_deref(), check, ditto, with_counts),
147            CoreCommands::Lint {
148                file,
149                format,
150                warn_error,
151            } => commands::lint(&file, &format, warn_error),
152            CoreCommands::Inspect { file, verbose } => commands::inspect(&file, verbose),
153            CoreCommands::Stats { file, tokens } => commands::stats(&file, tokens),
154        }
155    }
156}