mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
Add help text functionality for converters.
This commit is contained in:
parent
263e91c9f9
commit
a5fe59bb7c
@ -13,7 +13,8 @@
|
||||
// limitations under the License.
|
||||
|
||||
//! Contains code for converting a UCG Val into the environment variable output target.
|
||||
use std::io::Write;
|
||||
use std::fmt::Write as FmtWrite;
|
||||
use std::io::Write as IOWrite;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::build::Val;
|
||||
@ -28,7 +29,7 @@ impl EnvConverter {
|
||||
EnvConverter {}
|
||||
}
|
||||
|
||||
fn convert_tuple(&self, flds: &Vec<(String, Rc<Val>)>, w: &mut Write) -> ConvertResult {
|
||||
fn convert_tuple(&self, flds: &Vec<(String, Rc<Val>)>, w: &mut IOWrite) -> ConvertResult {
|
||||
for &(ref name, ref val) in flds.iter() {
|
||||
if val.is_tuple() {
|
||||
eprintln!("Skipping embedded tuple...");
|
||||
@ -44,12 +45,12 @@ impl EnvConverter {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn convert_list(&self, _items: &Vec<Rc<Val>>, _w: &mut Write) -> ConvertResult {
|
||||
fn convert_list(&self, _items: &Vec<Rc<Val>>, _w: &mut IOWrite) -> ConvertResult {
|
||||
eprintln!("Skipping List...");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write(&self, v: &Val, w: &mut Write) -> ConvertResult {
|
||||
fn write(&self, v: &Val, w: &mut IOWrite) -> ConvertResult {
|
||||
match v {
|
||||
&Val::Empty => {
|
||||
// Empty is a noop.
|
||||
@ -91,7 +92,7 @@ impl EnvConverter {
|
||||
}
|
||||
|
||||
impl Converter for EnvConverter {
|
||||
fn convert(&self, v: Rc<Val>, mut w: &mut Write) -> ConvertResult {
|
||||
fn convert(&self, v: Rc<Val>, mut w: &mut IOWrite) -> ConvertResult {
|
||||
self.write(&v, &mut w)
|
||||
}
|
||||
|
||||
@ -102,4 +103,21 @@ impl Converter for EnvConverter {
|
||||
fn description(&self) -> String {
|
||||
"Convert ucg Vals into environment variables.".to_string()
|
||||
}
|
||||
|
||||
#[allow(unused_must_use)]
|
||||
fn help(&self) -> String {
|
||||
let mut h = String::new();
|
||||
writeln!(
|
||||
h,
|
||||
"Env conversions expect a tuple. With keys represent the variable name."
|
||||
);
|
||||
writeln!(h, "");
|
||||
writeln!(h, "Allowed values can be:");
|
||||
writeln!(h, "- Bool converts to true or false");
|
||||
writeln!(h, "- Int");
|
||||
writeln!(h, "- Float");
|
||||
writeln!(h, "- String converted to a quoted string");
|
||||
writeln!(h, "- Functions and Modules are ignored.");
|
||||
h
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
//! Contains code for converting a UCG Val into an executable script output target.
|
||||
use std;
|
||||
use std::fmt::Write as FmtWrite;
|
||||
use std::io::{Cursor, Write};
|
||||
use std::rc::Rc;
|
||||
|
||||
@ -185,6 +186,40 @@ impl Converter for ExecConverter {
|
||||
fn description(&self) -> String {
|
||||
"Convert ucg Vals into an bash script with \nenvironment variables set and command line arguments sent..".to_string()
|
||||
}
|
||||
|
||||
#[allow(unused_must_use)]
|
||||
fn help(&self) -> String {
|
||||
let mut h = String::new();
|
||||
writeln!(
|
||||
h,
|
||||
"Exec conversions expect a tuple with an expected set of keys."
|
||||
);
|
||||
writeln!(h, "");
|
||||
writeln!(h, "The expected keys are:");
|
||||
writeln!(h, "");
|
||||
writeln!(h, "- command (string, required)");
|
||||
writeln!(h, "\t The command to run in the script.");
|
||||
writeln!(h, "");
|
||||
writeln!(h, "- env (tuple, optional)");
|
||||
writeln!(
|
||||
h,
|
||||
"\t Any environment variables that should be set in the script."
|
||||
);
|
||||
writeln!(
|
||||
h,
|
||||
"\t The env tuple is converted using the same rules as the env converter."
|
||||
);
|
||||
writeln!(h, "");
|
||||
writeln!(h, "- args (tuple, optional");
|
||||
writeln!(h, "\t Any command line arguments for the command line.");
|
||||
writeln!(
|
||||
h,
|
||||
"\t The arguments are converted using the same rules as the flags converter."
|
||||
);
|
||||
writeln!(h, "");
|
||||
writeln!(h, "- Functions and Modules are ignored.");
|
||||
h
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
//! Contains code for converting a UCG Val into the command line flag output target.
|
||||
use std::fmt::Write as FmtWrite;
|
||||
use std::io::Write;
|
||||
use std::rc::Rc;
|
||||
|
||||
@ -131,6 +132,37 @@ impl Converter for FlagConverter {
|
||||
fn description(&self) -> String {
|
||||
"Convert ucg Vals into command line flags.".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
// We need some unit tests for this now :D
|
||||
#[allow(unused_must_use)]
|
||||
fn help(&self) -> String {
|
||||
let mut h = String::new();
|
||||
writeln!(
|
||||
h,
|
||||
"Flags converts a tuple into a set of command line arguments for command line application."
|
||||
);
|
||||
writeln!(h, "");
|
||||
writeln!(h, "The flags are converted using the following rules:");
|
||||
writeln!(h, "");
|
||||
writeln!(h, "- keys in a tuple are converted into the argument name.");
|
||||
writeln!(
|
||||
h,
|
||||
"- values in a tuple are converted into the argument value."
|
||||
);
|
||||
writeln!(h, "- NULL values are not emitted");
|
||||
writeln!(
|
||||
h,
|
||||
"- lists expand out into an argument for each item in the list."
|
||||
);
|
||||
writeln!(h, "\te.g. {{foo = [1, 2]}} becomes --foo=1 --foo=2");
|
||||
writeln!(
|
||||
h,
|
||||
"- tuples expand out into an argument with the key as a prefix separated by a `.`."
|
||||
);
|
||||
writeln!(
|
||||
h,
|
||||
"\te.g. {{foo = {{bar = 1, baz = 2}}}} becomes --foo.bar=1 --foo.baz=2"
|
||||
);
|
||||
writeln!(h, "- Functions and Modules are ignored.");
|
||||
h
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
//! Flags contains code for converting a UCG Val into the json output target.
|
||||
use std;
|
||||
use std::error::Error;
|
||||
use std::fmt::Write as FmtWrite;
|
||||
use std::io::Write;
|
||||
use std::rc::Rc;
|
||||
|
||||
@ -135,6 +136,24 @@ impl Converter for JsonConverter {
|
||||
fn description(&self) -> String {
|
||||
"Convert ucg Vals into valid json.".to_string()
|
||||
}
|
||||
|
||||
#[allow(unused_must_use)]
|
||||
fn help(&self) -> String {
|
||||
let mut h = String::new();
|
||||
writeln!(h, "JSON conversions expect any ucg value.");
|
||||
writeln!(h, "");
|
||||
writeln!(
|
||||
h,
|
||||
"They are transformed into json using the following rules:"
|
||||
);
|
||||
writeln!(h, "- NULL becomes null");
|
||||
writeln!(h, "- tuples become objects {{}}");
|
||||
writeln!(h, "- lists become lists []");
|
||||
writeln!(h, "- Int and Float become numbers");
|
||||
writeln!(h, "- Strings become strings.");
|
||||
writeln!(h, "- Functions and Modules are ignored.");
|
||||
h
|
||||
}
|
||||
}
|
||||
|
||||
impl Importer for JsonConverter {
|
||||
|
@ -66,8 +66,6 @@ impl ConverterRegistry {
|
||||
pub fn get_converter_list(&self) -> Vec<(&String, &Box<traits::Converter>)> {
|
||||
self.converters.iter().collect()
|
||||
}
|
||||
|
||||
// TODO(jwall): Support converter help descriptions.
|
||||
}
|
||||
|
||||
pub struct ImporterRegistry {
|
||||
@ -109,6 +107,4 @@ impl ImporterRegistry {
|
||||
pub fn get_importer_list(&self) -> Vec<(&String, &Box<dyn traits::Importer>)> {
|
||||
self.importers.iter().collect()
|
||||
}
|
||||
|
||||
// TODO(jwall): Support converter help descriptions.
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
use std;
|
||||
use std::error;
|
||||
use std::error::Error;
|
||||
use std::fmt::Write as FmtWrite;
|
||||
use std::io::Write;
|
||||
use std::rc::Rc;
|
||||
|
||||
@ -127,6 +128,28 @@ impl Converter for TomlConverter {
|
||||
fn description(&self) -> String {
|
||||
"Convert ucg Vals into valid ucg.".to_string()
|
||||
}
|
||||
|
||||
#[allow(unused_must_use)]
|
||||
fn help(&self) -> String {
|
||||
let mut h = String::new();
|
||||
writeln!(h, "TOML conversions expect any ucg value.");
|
||||
writeln!(h, "");
|
||||
writeln!(
|
||||
h,
|
||||
"They are transformed into toml using the following rules:"
|
||||
);
|
||||
writeln!(h, "- tuples become maps {{}}");
|
||||
writeln!(h, "- lists become lists []");
|
||||
writeln!(h, "- Int becomes an Int");
|
||||
writeln!(h, "- Float becomes a Float");
|
||||
writeln!(h, "- Strings become Strings.");
|
||||
writeln!(
|
||||
h,
|
||||
"- NULL is not allowed in toml documents and will generate a compile error"
|
||||
);
|
||||
writeln!(h, "- Functions and Modules are ignored.");
|
||||
h
|
||||
}
|
||||
}
|
||||
|
||||
impl Importer for TomlConverter {
|
||||
|
@ -30,6 +30,7 @@ pub trait Converter {
|
||||
fn convert(&self, vs: Rc<Val>, w: &mut Write) -> ConvertResult;
|
||||
fn file_ext(&self) -> String;
|
||||
fn description(&self) -> String;
|
||||
fn help(&self) -> String;
|
||||
}
|
||||
|
||||
pub trait Importer {
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
use std;
|
||||
use std::error::Error;
|
||||
use std::fmt::Write as FmtWrite;
|
||||
use std::io::Write;
|
||||
use std::rc::Rc;
|
||||
|
||||
@ -234,4 +235,43 @@ impl Converter for XmlConverter {
|
||||
fn description(&self) -> String {
|
||||
String::from("Convert a ucg DSL into xml.")
|
||||
}
|
||||
|
||||
#[allow(unused_must_use)]
|
||||
fn help(&self) -> String {
|
||||
let mut h = String::new();
|
||||
writeln!(h, "XML converts ucg tuples into xml documents.");
|
||||
writeln!(h, "");
|
||||
writeln!(h, "The tuple converts into xml using a declarative DSL.");
|
||||
writeln!(h, "The top tuple describes the xml document:");
|
||||
writeln!(
|
||||
h,
|
||||
"{{
|
||||
version = \"1.1\" // Optional, Defaults to 1.1
|
||||
encoding = \"utf-8\" // Optional, Defaults to UTF-8
|
||||
standalone = true // Optional Defaults to false
|
||||
root = {{ // Required defines the root element of the document.
|
||||
name = \"top\",
|
||||
}}
|
||||
}};"
|
||||
);
|
||||
writeln!(h, "XML nodes are constructed like :");
|
||||
writeln!(
|
||||
h,
|
||||
"{{
|
||||
name = \"ns:element-name\",
|
||||
ns = {{
|
||||
prefix = \"myns\",
|
||||
uri = \"http://example.org\",
|
||||
}},
|
||||
attrs = {{
|
||||
id = \"foo\",
|
||||
}},
|
||||
children = [
|
||||
// child elements go here.
|
||||
],
|
||||
}};"
|
||||
);
|
||||
writeln!(h, "Text nodes are just strings.");
|
||||
h
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use std;
|
||||
use std::error::Error;
|
||||
use std::fmt::Write as FmtWrite;
|
||||
use std::io::Write;
|
||||
use std::rc::Rc;
|
||||
use std::result::Result;
|
||||
@ -132,6 +133,24 @@ impl Converter for YamlConverter {
|
||||
fn description(&self) -> String {
|
||||
"Convert ucg Vals into valid yaml.".to_string()
|
||||
}
|
||||
|
||||
#[allow(unused_must_use)]
|
||||
fn help(&self) -> String {
|
||||
let mut h = String::new();
|
||||
writeln!(h, "YAML conversions expect any ucg value.");
|
||||
writeln!(h, "");
|
||||
writeln!(
|
||||
h,
|
||||
"They are transformed into toml using the following rules:"
|
||||
);
|
||||
writeln!(h, "- tuples become maps {{}}");
|
||||
writeln!(h, "- lists become lists []");
|
||||
writeln!(h, "- Int becomes an Int");
|
||||
writeln!(h, "- Float becomes a Float");
|
||||
writeln!(h, "- Strings become Strings.");
|
||||
writeln!(h, "- Functions and Modules are ignored.");
|
||||
h
|
||||
}
|
||||
}
|
||||
|
||||
impl Importer for YamlConverter {
|
||||
|
38
src/main.rs
38
src/main.rs
@ -55,6 +55,7 @@ fn do_flags<'a, 'b>() -> clap::App<'a, 'b> {
|
||||
)
|
||||
(@subcommand converters =>
|
||||
(about: "list the available converters")
|
||||
(@arg converter: "Converter name to get help for.")
|
||||
)
|
||||
(@subcommand importers =>
|
||||
(about: "list the available importers for includes")
|
||||
@ -252,7 +253,6 @@ fn inspect_command(
|
||||
builder.set_strict(strict);
|
||||
match registry.get_converter(target) {
|
||||
Some(converter) => {
|
||||
// TODO(jwall): We should warn if this is a test file.
|
||||
let result = builder.build(file);
|
||||
if !result.is_ok() {
|
||||
eprintln!("{:?}", result.err().unwrap());
|
||||
@ -393,14 +393,32 @@ fn test_command(
|
||||
process::exit(0);
|
||||
}
|
||||
|
||||
fn converters_command(registry: &ConverterRegistry) {
|
||||
println!("Available converters:");
|
||||
println!("");
|
||||
for (name, c) in registry.get_converter_list().iter() {
|
||||
println!("- {}", name);
|
||||
println!(" Description: {}", c.description());
|
||||
println!(" Output Extension: `.{}`", c.file_ext());
|
||||
fn converters_command(matches: &clap::ArgMatches, registry: &ConverterRegistry) {
|
||||
if let Some(ref cname) = matches.value_of("converter") {
|
||||
let mut found = false;
|
||||
for (name, c) in registry.get_converter_list().iter() {
|
||||
if cname == name {
|
||||
println!("* {}", name);
|
||||
println!("Description: {}", c.description());
|
||||
println!("Output Extension: `.{}`", c.file_ext());
|
||||
println!("");
|
||||
println!("{}", c.help());
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
println!("No such converter {}", cname);
|
||||
process::exit(1);
|
||||
}
|
||||
} else {
|
||||
println!("Available converters:");
|
||||
println!("");
|
||||
for (name, c) in registry.get_converter_list().iter() {
|
||||
println!("* {}", name);
|
||||
println!("Description: {}", c.description());
|
||||
println!("Output Extension: `.{}`", c.file_ext());
|
||||
println!("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -457,8 +475,8 @@ fn main() {
|
||||
build_command(matches, &import_paths, cache, ®istry, strict);
|
||||
} else if let Some(matches) = app_matches.subcommand_matches("test") {
|
||||
test_command(matches, &import_paths, cache, ®istry, strict);
|
||||
} else if let Some(_) = app_matches.subcommand_matches("converters") {
|
||||
converters_command(®istry)
|
||||
} else if let Some(matches) = app_matches.subcommand_matches("converters") {
|
||||
converters_command(matches, ®istry)
|
||||
} else if let Some(_) = app_matches.subcommand_matches("importers") {
|
||||
let registry = ImporterRegistry::make_registry();
|
||||
importers_command(®istry)
|
||||
|
Loading…
x
Reference in New Issue
Block a user