Skip to main content

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 reference validation (all references must resolve)
50        #[arg(short, long)]
51        strict: bool,
52
53        /// Use lenient parsing mode (constraint violations become null)
54        #[arg(short, long)]
55        lenient: bool,
56    },
57
58    /// Format a HEDL file to canonical form
59    ///
60    /// Reformats a HEDL file to its canonical representation. Supports various
61    /// formatting options including ditto optimization and automatic count hints.
62    Format {
63        /// Input file path
64        #[arg(value_name = "FILE")]
65        file: String,
66
67        /// Output file path (defaults to stdout)
68        #[arg(short, long)]
69        output: Option<String>,
70
71        /// Check only (exit 1 if not canonical)
72        #[arg(short, long)]
73        check: bool,
74
75        /// Use ditto optimization
76        #[arg(long, default_value = "true")]
77        ditto: bool,
78
79        /// Automatically add count hints to all matrix lists
80        #[arg(long)]
81        with_counts: bool,
82    },
83
84    /// Lint a HEDL file for best practices
85    ///
86    /// Analyzes a HEDL file for style issues, best practices violations, and
87    /// potential problems. Can output results in text or JSON format.
88    Lint {
89        /// Input file path
90        #[arg(value_name = "FILE")]
91        file: String,
92
93        /// Output format (text, json)
94        #[arg(short, long, default_value = "text")]
95        format: String,
96
97        /// Treat warnings as errors
98        #[arg(short = 'W', long)]
99        warn_error: bool,
100    },
101
102    /// Print parsed structure (debug)
103    ///
104    /// Displays the internal structure of a HEDL file as a tree, useful for
105    /// debugging and understanding how HEDL parses the file.
106    Inspect {
107        /// Input file path
108        #[arg(value_name = "FILE")]
109        file: String,
110
111        /// Show detailed internal structure
112        #[arg(short, long)]
113        verbose: bool,
114    },
115
116    /// Show size/token savings vs other formats
117    ///
118    /// Analyzes a HEDL file and compares its size and token count against
119    /// equivalent representations in JSON, YAML, XML, CSV, and Parquet.
120    Stats {
121        /// Input HEDL file
122        #[arg(value_name = "FILE")]
123        file: String,
124
125        /// Show estimated token counts for LLM context
126        #[arg(short, long)]
127        tokens: bool,
128    },
129}
130
131impl CoreCommands {
132    /// Execute the core command.
133    ///
134    /// # Returns
135    ///
136    /// Returns `Ok(())` on success, or an error message on failure.
137    ///
138    /// # Errors
139    ///
140    /// Returns `Err` if the command execution fails.
141    pub fn execute(self) -> Result<(), crate::error::CliError> {
142        match self {
143            CoreCommands::Validate {
144                file,
145                strict,
146                lenient,
147            } => commands::validate(&file, strict, lenient),
148            CoreCommands::Format {
149                file,
150                output,
151                check,
152                ditto,
153                with_counts,
154            } => commands::format(&file, output.as_deref(), check, ditto, with_counts),
155            CoreCommands::Lint {
156                file,
157                format,
158                warn_error,
159            } => commands::lint(&file, &format, warn_error),
160            CoreCommands::Inspect { file, verbose } => commands::inspect(&file, verbose),
161            CoreCommands::Stats { file, tokens } => commands::stats(&file, tokens),
162        }
163    }
164}