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.
|
// limitations under the License.
|
||||||
|
|
||||||
//! Contains code for converting a UCG Val into the environment variable output target.
|
//! 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 std::rc::Rc;
|
||||||
|
|
||||||
use crate::build::Val;
|
use crate::build::Val;
|
||||||
@ -28,7 +29,7 @@ impl EnvConverter {
|
|||||||
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() {
|
for &(ref name, ref val) in flds.iter() {
|
||||||
if val.is_tuple() {
|
if val.is_tuple() {
|
||||||
eprintln!("Skipping embedded tuple...");
|
eprintln!("Skipping embedded tuple...");
|
||||||
@ -44,12 +45,12 @@ impl EnvConverter {
|
|||||||
Ok(())
|
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...");
|
eprintln!("Skipping List...");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&self, v: &Val, w: &mut Write) -> ConvertResult {
|
fn write(&self, v: &Val, w: &mut IOWrite) -> ConvertResult {
|
||||||
match v {
|
match v {
|
||||||
&Val::Empty => {
|
&Val::Empty => {
|
||||||
// Empty is a noop.
|
// Empty is a noop.
|
||||||
@ -91,7 +92,7 @@ impl EnvConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Converter for 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)
|
self.write(&v, &mut w)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,4 +103,21 @@ impl Converter for EnvConverter {
|
|||||||
fn description(&self) -> String {
|
fn description(&self) -> String {
|
||||||
"Convert ucg Vals into environment variables.".to_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.
|
//! Contains code for converting a UCG Val into an executable script output target.
|
||||||
use std;
|
use std;
|
||||||
|
use std::fmt::Write as FmtWrite;
|
||||||
use std::io::{Cursor, Write};
|
use std::io::{Cursor, Write};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@ -185,6 +186,40 @@ impl Converter for ExecConverter {
|
|||||||
fn description(&self) -> String {
|
fn description(&self) -> String {
|
||||||
"Convert ucg Vals into an bash script with \nenvironment variables set and command line arguments sent..".to_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)]
|
#[cfg(test)]
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
//! Contains code for converting a UCG Val into the command line flag output target.
|
//! 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::io::Write;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@ -131,6 +132,37 @@ impl Converter for FlagConverter {
|
|||||||
fn description(&self) -> String {
|
fn description(&self) -> String {
|
||||||
"Convert ucg Vals into command line flags.".to_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.
|
//! Flags contains code for converting a UCG Val into the json output target.
|
||||||
use std;
|
use std;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::fmt::Write as FmtWrite;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@ -135,6 +136,24 @@ impl Converter for JsonConverter {
|
|||||||
fn description(&self) -> String {
|
fn description(&self) -> String {
|
||||||
"Convert ucg Vals into valid json.".to_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 {
|
impl Importer for JsonConverter {
|
||||||
|
@ -66,8 +66,6 @@ impl ConverterRegistry {
|
|||||||
pub fn get_converter_list(&self) -> Vec<(&String, &Box<traits::Converter>)> {
|
pub fn get_converter_list(&self) -> Vec<(&String, &Box<traits::Converter>)> {
|
||||||
self.converters.iter().collect()
|
self.converters.iter().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(jwall): Support converter help descriptions.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ImporterRegistry {
|
pub struct ImporterRegistry {
|
||||||
@ -109,6 +107,4 @@ impl ImporterRegistry {
|
|||||||
pub fn get_importer_list(&self) -> Vec<(&String, &Box<dyn traits::Importer>)> {
|
pub fn get_importer_list(&self) -> Vec<(&String, &Box<dyn traits::Importer>)> {
|
||||||
self.importers.iter().collect()
|
self.importers.iter().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(jwall): Support converter help descriptions.
|
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
use std;
|
use std;
|
||||||
use std::error;
|
use std::error;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::fmt::Write as FmtWrite;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@ -127,6 +128,28 @@ impl Converter for TomlConverter {
|
|||||||
fn description(&self) -> String {
|
fn description(&self) -> String {
|
||||||
"Convert ucg Vals into valid ucg.".to_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 {
|
impl Importer for TomlConverter {
|
||||||
|
@ -30,6 +30,7 @@ pub trait Converter {
|
|||||||
fn convert(&self, vs: Rc<Val>, w: &mut Write) -> ConvertResult;
|
fn convert(&self, vs: Rc<Val>, w: &mut Write) -> ConvertResult;
|
||||||
fn file_ext(&self) -> String;
|
fn file_ext(&self) -> String;
|
||||||
fn description(&self) -> String;
|
fn description(&self) -> String;
|
||||||
|
fn help(&self) -> String;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Importer {
|
pub trait Importer {
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
use std;
|
use std;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::fmt::Write as FmtWrite;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@ -234,4 +235,43 @@ impl Converter for XmlConverter {
|
|||||||
fn description(&self) -> String {
|
fn description(&self) -> String {
|
||||||
String::from("Convert a ucg DSL into xml.")
|
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;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::fmt::Write as FmtWrite;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::result::Result;
|
use std::result::Result;
|
||||||
@ -132,6 +133,24 @@ impl Converter for YamlConverter {
|
|||||||
fn description(&self) -> String {
|
fn description(&self) -> String {
|
||||||
"Convert ucg Vals into valid yaml.".to_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 {
|
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 =>
|
(@subcommand converters =>
|
||||||
(about: "list the available converters")
|
(about: "list the available converters")
|
||||||
|
(@arg converter: "Converter name to get help for.")
|
||||||
)
|
)
|
||||||
(@subcommand importers =>
|
(@subcommand importers =>
|
||||||
(about: "list the available importers for includes")
|
(about: "list the available importers for includes")
|
||||||
@ -252,7 +253,6 @@ fn inspect_command(
|
|||||||
builder.set_strict(strict);
|
builder.set_strict(strict);
|
||||||
match registry.get_converter(target) {
|
match registry.get_converter(target) {
|
||||||
Some(converter) => {
|
Some(converter) => {
|
||||||
// TODO(jwall): We should warn if this is a test file.
|
|
||||||
let result = builder.build(file);
|
let result = builder.build(file);
|
||||||
if !result.is_ok() {
|
if !result.is_ok() {
|
||||||
eprintln!("{:?}", result.err().unwrap());
|
eprintln!("{:?}", result.err().unwrap());
|
||||||
@ -393,14 +393,32 @@ fn test_command(
|
|||||||
process::exit(0);
|
process::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn converters_command(registry: &ConverterRegistry) {
|
fn converters_command(matches: &clap::ArgMatches, registry: &ConverterRegistry) {
|
||||||
println!("Available converters:");
|
if let Some(ref cname) = matches.value_of("converter") {
|
||||||
println!("");
|
let mut found = false;
|
||||||
for (name, c) in registry.get_converter_list().iter() {
|
for (name, c) in registry.get_converter_list().iter() {
|
||||||
println!("- {}", name);
|
if cname == name {
|
||||||
println!(" Description: {}", c.description());
|
println!("* {}", name);
|
||||||
println!(" Output Extension: `.{}`", c.file_ext());
|
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!("");
|
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);
|
build_command(matches, &import_paths, cache, ®istry, strict);
|
||||||
} else if let Some(matches) = app_matches.subcommand_matches("test") {
|
} else if let Some(matches) = app_matches.subcommand_matches("test") {
|
||||||
test_command(matches, &import_paths, cache, ®istry, strict);
|
test_command(matches, &import_paths, cache, ®istry, strict);
|
||||||
} else if let Some(_) = app_matches.subcommand_matches("converters") {
|
} else if let Some(matches) = app_matches.subcommand_matches("converters") {
|
||||||
converters_command(®istry)
|
converters_command(matches, ®istry)
|
||||||
} else if let Some(_) = app_matches.subcommand_matches("importers") {
|
} else if let Some(_) = app_matches.subcommand_matches("importers") {
|
||||||
let registry = ImporterRegistry::make_registry();
|
let registry = ImporterRegistry::make_registry();
|
||||||
importers_command(®istry)
|
importers_command(®istry)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user