1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
//! Checked invocation and successful-output contracts for [`clap`] applications.
//!
//! Clap remains authoritative for parsing. `clap_schema` reflects a canonical agent-facing
//! invocation contract from the built command tree and binds each contract-visible invocable
//! command to the JSON shape produced by its real handler.
//!
//! Every contract-visible executable command is identified by the Rust payload type already present
//! on its Clap variant. A canonical `#[schema_handler(...)]` contract associates that type with the
//! selected handler's declared `Result<T, E>`, which remains the sole source of its successful
//! output contract. For non-unit `T`, the crate requires
//! `T: schemars::JsonSchema + 'static` and emits Schemars' serialization-view JSON Schema.
//! `Result<(), E>` has no output contract.
//!
//! # Derive API
//!
//! ```
//! use clap::{Args, Parser, Subcommand};
//! use clap_schema::{CliSchema, CommandSchema, schema_handler};
//! use schemars::JsonSchema;
//!
//! #[derive(Debug, Parser, CliSchema)]
//! struct Cli {
//! #[command(subcommand)]
//! command: Commands,
//! }
//!
//! #[derive(Debug, Subcommand, CommandSchema)]
//! enum Commands {
//! Create(CreateArgs),
//! }
//!
//! #[derive(Debug, Args)]
//! struct CreateArgs {
//! #[arg(long)]
//! name: String,
//! }
//!
//! #[derive(Debug, JsonSchema)]
//! struct Item {
//! id: u64,
//! name: String,
//! }
//!
//! #[schema_handler(CreateArgs)]
//! async fn create(args: CreateArgs) -> Result<Item, std::io::Error> {
//! Ok(Item { id: 1, name: args.name })
//! }
//!
//! let contract = Cli::schema()?;
//! let create = contract.command_for::<CreateArgs>().expect("create command is registered");
//! let output = create.output.as_ref().expect("create output");
//! assert_eq!(output.get("type").and_then(serde_json::Value::as_str), Some("object"));
//! assert!(create.options.iter().any(|argument| argument.name == "--name"));
//! let root = contract.schema(&clap_schema::SchemaRequest::default())?;
//! assert_eq!(root.subcommands.len(), 1);
//! # Ok::<(), clap_schema::Error>(())
//! ```
//!
//! `CreateArgs` is the Clap payload type that identifies the executable command. `CommandSchema`
//! gets that identity from the variant, while the schema handler supplies its successful-output
//! contract; removing the handler or attaching a second canonical handler therefore fails to
//! compile. Derive-based executable
//! commands use one named tuple payload; an empty
//! `Args` type represents a command with no arguments.
//!
//! # Nested command shapes
//!
//! Normal `#[command(subcommand)]` and `#[command(flatten)]` enum nesting is followed
//! automatically. When an `Args` payload itself contains a subcommand field, derive
//! [`CommandSchema`] on that payload:
//!
//! ```
//! use clap::{Args, Parser, Subcommand};
//! use clap_schema::{CliSchema, CommandSchema, schema_handler};
//!
//! #[derive(Parser, CliSchema)]
//! struct Cli {
//! #[command(subcommand)]
//! command: Commands,
//! }
//!
//! #[derive(Subcommand, CommandSchema)]
//! enum Commands {
//! Stash(StashArgs),
//! }
//!
//! #[derive(Args, CommandSchema)]
//! struct StashArgs {
//! #[command(subcommand)]
//! command: Option<StashCommands>,
//! }
//!
//! #[derive(Subcommand, CommandSchema)]
//! enum StashCommands {
//! List(ListArgs),
//! }
//!
//! #[derive(Args)]
//! struct ListArgs {}
//!
//! #[schema_handler(StashArgs)]
//! fn stash_default(_args: StashArgs) -> Result<(), std::convert::Infallible> {
//! Ok(())
//! }
//!
//! #[schema_handler(ListArgs)]
//! fn list(_args: ListArgs) -> Result<(), std::convert::Infallible> {
//! Ok(())
//! }
//!
//! let contract = Cli::schema()?;
//! let stash = contract.command_for::<StashArgs>().expect("stash command is registered");
//! let list = contract.command_for::<ListArgs>().expect("list command is registered");
//! assert!(stash.invocable);
//! assert_eq!(list.path.len(), 2);
//! # Ok::<(), clap_schema::Error>(())
//! ```
//!
//! The child enum type is therefore read from the same field Clap parses instead of being repeated
//! in schema metadata. A required subcommand field makes the parent a group. An
//! `Option<Subcommands>` field makes the parent directly invocable and therefore requires its own
//! `#[schema_handler(...)]` contract.
//!
//! # Schema handlers
//!
//! Free handlers use `#[schema_handler(Type)]`, where `Type` is the command payload. Synchronous,
//! `const fn`, and asynchronous functions are supported, and their arguments are otherwise
//! unrestricted. When execution already lives on the command type, annotate its inherent impl with
//! the handler method name instead:
//!
//! ```
//! use clap_schema::schema_handler;
//! use schemars::JsonSchema;
//!
//! struct GetArgs;
//!
//! #[derive(JsonSchema)]
//! struct Item {
//! id: u64,
//! }
//!
//! #[schema_handler(run)]
//! impl GetArgs {
//! async fn run(self, _context: &str) -> Result<Item, std::io::Error> {
//! Ok(Item { id: 1 })
//! }
//! }
//! ```
//!
//! In the impl form, the impl's `Self` type is the command identity and the named inherent method
//! supplies the output contract. Generic handlers and opaque `impl Trait` return types are rejected
//! because they do not identify one concrete output contract.
//!
//! # Builder-style Clap
//!
//! Builder applications use the same handler-derived command contracts. There is no API
//! for declaring an output type manually:
//!
//! ```
//! use clap::Command;
//! use clap_schema::{ContractBuilder, schema_handler};
//! use schemars::JsonSchema;
//!
//! #[derive(JsonSchema)]
//! struct Created {
//! id: u64,
//! }
//!
//! struct CreateCommand;
//!
//! #[schema_handler(CreateCommand)]
//! fn create(_command: CreateCommand) -> Result<Created, std::io::Error> {
//! Ok(Created { id: 1 })
//! }
//!
//! let cli = Command::new("example").subcommand(Command::new("create"));
//! let contract = ContractBuilder::new(cli).command::<CreateCommand>(["create"]).build()?;
//! assert!(contract.command_for::<CreateCommand>().and_then(|command| command.output).is_some());
//! # Ok::<(), clap_schema::Error>(())
//! ```
//!
//! # Application-defined schema extensions
//!
//! Applications may declare a schema for metadata that they add to their own machine-facing
//! documents. `clap_schema` handles only the schema side: it never stores or serializes the
//! application's concrete metadata values.
//!
//! ```
//! use clap::{Args, Parser, Subcommand};
//! use clap_schema::{CliSchema, CommandSchema, schema_handler};
//! use schemars::JsonSchema;
//!
//! #[derive(Debug, JsonSchema)]
//! struct CommandMetadata {
//! destructive: bool,
//! }
//!
//! #[derive(Debug, JsonSchema)]
//! #[schemars(rename_all = "camelCase")]
//! struct PaginationMetadata {
//! cursor_argument: String,
//! }
//!
//! #[derive(Debug, Parser, CliSchema)]
//! #[schema(extend = CommandMetadata)]
//! struct Cli {
//! #[command(subcommand)]
//! command: Commands,
//! }
//!
//! #[derive(Debug, Subcommand, CommandSchema)]
//! enum Commands {
//! #[schema(extend = PaginationMetadata)]
//! List(ListArgs),
//! }
//!
//! #[derive(Debug, Args)]
//! struct ListArgs {
//! #[arg(long)]
//! cursor: Option<String>,
//! }
//!
//! #[derive(Debug, JsonSchema)]
//! #[schemars(rename_all = "camelCase")]
//! struct Page {
//! next_cursor: Option<String>,
//! }
//!
//! #[schema_handler(ListArgs)]
//! fn list(_command: ListArgs) -> Result<Page, std::convert::Infallible> {
//! Ok(Page { next_cursor: None })
//! }
//!
//! let contract = Cli::schema()?;
//! assert_eq!(contract.extended_schema().unwrap()["type"], "object");
//! assert_eq!(
//! contract.extended_schema_for_command::<ListArgs>().unwrap()["allOf"]
//! .as_array()
//! .map(Vec::len),
//! Some(2),
//! );
//! # Ok::<(), clap_schema::Error>(())
//! ```
//!
//! Root `extend = Type` declares the application-wide vocabulary. An executable
//! `CommandSchema` variant may add `extend = Type` as a command-specific supplement. The
//! effective schema is the intersection of both layers, represented with JSON Schema `allOf`;
//! it is not a shallow schema merge. Commands without a supplement inherit the application-wide
//! schema unchanged. Because every `allOf` branch validates the same value, applications must
//! choose extension schema types that compose correctly; `clap_schema` does not relax closed object
//! schemas or otherwise rewrite application-defined constraints.
//!
//! Metadata types need only [`schemars::JsonSchema`]. Applications commonly also implement
//! [`serde::Serialize`] on those types because the application constructs the actual metadata
//! values, but that value never crosses `clap_schema`. The application is responsible for making
//! sure its emitted value satisfies the extension schema it exposes. Builder-style applications
//! use [`ContractBuilder::extend`] and [`ContractBuilder::command_with_extension`].
//!
//! The runnable `application_extension` example demonstrates application-owned value construction,
//! flattening application and command layers into one metadata value, and choosing the final
//! machine-facing document shape.
//!
//! # Scope
//!
//! The wire model describes a canonical process-style invocation contract without serializing
//! Clap's own help representation. Global argument scope, positional order, canonical option
//! spellings, value arity, lexical defaults and possible values, delimiters, terminators,
//! conflicts, repeatability, exclusivity, required equals syntax, and required option-terminator
//! syntax are reflected from Clap's built command tree. Human-facing aliases, short alternatives,
//! value placeholders, and rendered usage strings are intentionally omitted. Input values remain
//! lexical rather than inferring Rust parser result types. Clap remains authoritative for
//! parser-specific validation, and argv framing modes outside the process model are rejected. A
//! present output schema means the command's successful value has a machine-readable JSON Schema;
//! absence means no typed successful-output contract is declared. See `SPECIFICATION.md` for the
//! complete wire contract and reflection boundary.
extern crate self as clap_schema;
pub use ;
pub use ;
pub use ;
/// Trait implemented by a machine-contract-aware root Clap parser.
///
/// Prefer `#[derive(CliSchema)]` for derive-based Clap applications. A root with no subcommand
/// field, or with an optional `#[command(subcommand)]` field, is directly invocable and therefore
/// requires its own schema handler contract. Root derives may declare an application-defined
/// extension schema with `#[schema(extend = Type)]`.
/// Trait implemented by types that contribute nested command structure to a CLI contract.
///
/// Prefer `#[derive(CommandSchema)]` for derive-based Clap applications. Derive it on Clap
/// `Subcommand` enums and on `Args` wrappers that contain one `#[command(subcommand)]` field. The
/// wrapper's `CommandSchema` implementation is discovered from its payload type, so parent variants
/// need no additional `clap_schema` topology annotation. A required wrapper field contributes only
/// child commands; `Option<Subcommands>` also makes the wrapper itself executable. Executable
/// variants use one named tuple payload with one canonical schema handler supplying its
/// successful-output contract.