///|
fn option_type_to_string(t : OptionType) -> String {
match t {
StringOpt => "string"
BoolOpt => "bool"
IntOpt => "int"
Int64Opt => "int64"
UIntOpt => "uint"
UInt64Opt => "uint64"
DoubleOpt => "double"
}
}
///|
priv struct OptionSchema {
option : StoredOption
}
///|
let option_schema_type_lens : @lens.Lens[String] = @lens.root().string("type")
///|
let option_schema_description_lens : @lens.Lens[String] = @lens.root().string(
"description",
)
///|
let option_schema_required_lens : @lens.Lens[Bool] = @lens.root().bool(
"required",
)
///|
let option_schema_multiple_lens : @lens.Lens[Bool] = @lens.root().bool(
"multiple",
)
///|
let option_schema_interactive_lens : @lens.Lens[Bool] = @lens.root().bool(
"interactive",
)
///|
let option_schema_style_lens : @lens.PresenceLens[String] = @lens.root()
.string("style")
.optional()
///|
let option_schema_short_lens : @lens.PresenceLens[String] = @lens.root()
.string("short")
.optional()
///|
let option_schema_env_lens : @lens.PresenceLens[String] = @lens.root()
.string("env")
.optional()
///|
let option_schema_config_lens : @lens.PresenceLens[String] = @lens.root()
.string("config")
.optional()
///|
let option_schema_default_lens : @lens.PresenceLens[String] = @lens.root()
.string("default")
.optional()
///|
impl ToJson for OptionSchema with fn to_json(self) -> Json {
let option = self.option
let metadata = option.metadata
let builder = @lens.JsonBuilder::JsonBuilder()
option_schema_type_lens.set_or_abort(
builder,
option_type_to_string(metadata.type_),
)
option_schema_description_lens.set_or_abort(builder, metadata.description)
option_schema_required_lens.set_or_abort(builder, metadata.required)
option_schema_multiple_lens.set_or_abort(builder, metadata.multiple)
option_schema_interactive_lens.set_or_abort(builder, metadata.interactive)
option_schema_style_lens.set_or_abort(
builder,
if metadata.type_ == BoolOpt {
Some("flag")
} else {
None
},
)
option_schema_short_lens.set_or_abort(
builder,
if metadata.short != no_short {
Some(metadata.short.to_string())
} else {
None
},
)
option_schema_env_lens.set_or_abort(builder, metadata.env)
option_schema_config_lens.set_or_abort(builder, option.config)
option_schema_default_lens.set_or_abort(builder, metadata.default_value)
builder.to_json()
}
///|
extend OptionSchema with ToJson::{to_json}
///|
priv struct PositionSchema {
position : StoredPosition
}
///|
let position_schema_type_lens : @lens.Lens[String] = @lens.root().string("type")
///|
let position_schema_description_lens : @lens.Lens[String] = @lens.root().string(
"description",
)
///|
let position_schema_required_lens : @lens.Lens[Bool] = @lens.root().bool(
"required",
)
///|
let position_schema_multiple_lens : @lens.Lens[Bool] = @lens.root().bool(
"multiple",
)
///|
let position_schema_interactive_lens : @lens.Lens[Bool] = @lens.root().bool(
"interactive",
)
///|
let position_schema_config_lens : @lens.PresenceLens[String] = @lens.root()
.string("config")
.optional()
///|
impl ToJson for PositionSchema with fn to_json(self) -> Json {
let position = self.position
let metadata = position.metadata
let builder = @lens.JsonBuilder::JsonBuilder()
position_schema_type_lens.set_or_abort(
builder,
option_type_to_string(metadata.type_),
)
position_schema_description_lens.set_or_abort(builder, metadata.description)
position_schema_required_lens.set_or_abort(builder, metadata.required)
position_schema_multiple_lens.set_or_abort(builder, metadata.multiple)
position_schema_interactive_lens.set_or_abort(builder, metadata.interactive)
position_schema_config_lens.set_or_abort(builder, position.config)
builder.to_json()
}
///|
extend PositionSchema with ToJson::{to_json}
///|
fn generate_example(cmd_path : String, options : Array[StoredOption]) -> String {
let parts : Array[String] = [cmd_path]
for opt in options {
if opt.metadata.required {
parts.push("--" + opt.name + " <" + opt.name + ">")
}
}
parts.join(" ")
}
///|
priv struct CommandSchema {
command : CommandDef
path : String
}
///|
let command_schema_description_lens : @lens.Lens[String] = @lens.root().string(
"description",
)
///|
let command_schema_options_lens : @lens.PresenceLens[Json] = @lens.root()
.json("options")
.optional()
///|
let command_schema_positionals_lens : @lens.PresenceLens[Json] = @lens.root()
.json("positionals")
.optional()
///|
let command_schema_examples_lens : @lens.PresenceLens[Array[String]] = @lens.root()
.string("examples")
.array()
.optional()
///|
let command_schema_commands_lens : @lens.PresenceLens[Json] = @lens.root()
.json("commands")
.optional()
///|
impl ToJson for CommandSchema with fn to_json(self) -> Json {
let command = self.command
let builder = @lens.JsonBuilder::JsonBuilder()
command_schema_description_lens.set_or_abort(builder, command.description)
let options : Map[String, Json] = Map([])
for option in command.options {
options[option.name] = OptionSchema::{ option, }.to_json()
}
command_schema_options_lens.set_or_abort(
builder,
if options.is_empty() {
None
} else {
Some(options.to_json())
},
)
let positionals : Map[String, Json] = Map([])
for position in command.positionals {
positionals[position.name] = PositionSchema::{ position, }.to_json()
}
command_schema_positionals_lens.set_or_abort(
builder,
if positionals.is_empty() {
None
} else {
Some(positionals.to_json())
},
)
command_schema_examples_lens.set_or_abort(
builder,
if command.examples.length() > 0 {
Some(command.examples)
} else if command.options.length() > 0 || command.positionals.length() > 0 {
Some([generate_example(self.path, command.options)])
} else {
None
},
)
let subcommands : Map[String, Json] = Map([])
for subcommand in command.subcommands {
subcommands[subcommand.name] = CommandSchema::{
command: subcommand,
path: self.path + " " + subcommand.name,
}.to_json()
}
command_schema_commands_lens.set_or_abort(
builder,
if subcommands.is_empty() {
None
} else {
Some(subcommands.to_json())
},
)
builder.to_json()
}
///|
extend CommandSchema with ToJson::{to_json}
///|
let cli_schema_name_lens : @lens.Lens[String] = @lens.root().string("name")
///|
let cli_schema_version_lens : @lens.Lens[String] = @lens.root().string(
"version",
)
///|
let cli_schema_description_lens : @lens.Lens[String] = @lens.root().string(
"description",
)
///|
let cli_schema_options_lens : @lens.PresenceLens[Json] = @lens.root()
.json("options")
.optional()
///|
let cli_schema_positionals_lens : @lens.PresenceLens[Json] = @lens.root()
.json("positionals")
.optional()
///|
let cli_schema_commands_lens : @lens.PresenceLens[Json] = @lens.root()
.json("commands")
.optional()
///|
pub impl ToJson for CliApp with fn to_json(self) -> Json {
let builder = @lens.JsonBuilder::JsonBuilder()
cli_schema_name_lens.set_or_abort(builder, self.name)
cli_schema_version_lens.set_or_abort(builder, self.version)
cli_schema_description_lens.set_or_abort(builder, self.description)
let options : Map[String, Json] = Map([])
for option in self.root_options {
options[option.name] = OptionSchema::{ option, }.to_json()
}
cli_schema_options_lens.set_or_abort(
builder,
if options.is_empty() {
None
} else {
Some(options.to_json())
},
)
let positionals : Map[String, Json] = Map([])
for position in self.root_positionals {
positionals[position.name] = PositionSchema::{ position, }.to_json()
}
cli_schema_positionals_lens.set_or_abort(
builder,
if positionals.is_empty() {
None
} else {
Some(positionals.to_json())
},
)
let commands : Map[String, Json] = Map([])
for command in self.commands {
commands[command.name] = CommandSchema::{
command,
path: self.name + " " + command.name,
}.to_json()
}
cli_schema_commands_lens.set_or_abort(
builder,
if commands.is_empty() {
None
} else {
Some(commands.to_json())
},
)
builder.to_json()
}
///|
extend CliApp with ToJson::{to_json}
///|
pub fn CliApp::render_schema(self : CliApp) -> String {
self.to_json().stringify()
}