libxo, generating human strings and xml/json/etc. from soemthing like xo_emit(" {:lines/%7ju} {:words/%7ju} {:characters/%7ju} {d:filename/%s}\n", linect, wordct, charct, file);
teaching serde to output json-ld(adding context annotations)
one root message type → generate JSON schema as CLI API doc for other CLI apps to consume
composing types means composing their output. should work for human representation but will probably require the ability overwrite based on context
Pascal’s ideas for a CLI-focused MVP
Pitch
We should make a library that makes it easy/convenient to output stuff for humans on a console(so people will want to use this instead of println!), which also gives you common formatting options, and that gives you JSON output for free.
What to do
Define structs/enums
derive Serialize
implement a trait(let’s call it O for simplicity) that turns the fields’ data into an element tree
Provide a way to write that O impl super easy
Provide a bunch of built-in“tags”(to print stuff in bold, colored) and a macro for JSX-style syntax?
Provide a macro to make this whole thing a one-liner? Strawman proposal: define_message! { Message { code: i32, message: String, } => <bold>{code}</bold>: {message} }
Make sure these compose: Assume we have a define_message! { ErrorCode { code: i32 } => if code < 0 { <span fs="red">Error ({code}):</span> } else { <span>Info ({code})</span> } } then the above Message definition should still work with just replacing i32 with ErrorCode
Output stuff like output!(Message { code: 42, message: "Foobar".into() });
we should evaluate how valuable single-line define-and-output might be, especially if people are used to println! and log
Init a drain for the outputs at the start of your fn main(likecli_output_thing::init()?;) that sets up coloring, human vs. json output, etc.
(optional) also provide a replacement for the log macros ( info!, warn!, err!, etc.) and an adapter for the std log crate to work with our drain(maybe build on slog)
Further steps
We should try to keep in mind that most of the suggestions here can be implement in a more generic way — that element tree thing could also work for other markup formats(like roff or, obviously, html).
A next increment could add support for getting more information out of a root Message type: Similar to a library that exposes a single Error type, a CLI could expose a Message type that defines all(machine-readable) output(e.g. by rendering Rust types with serde annotation to a JSON schema file). This is something that will probably not“sell” our library to most users, but if it turns out to be easy to get, would benefit us in the long run.
There is a trade-off between“meticulously defining types and organizing them in a hierarchy” and"just use single-line define-and-output(a.k.a. ad-hoc formatting) everywhere” that we should discuss and present to users.
not easy: weird multi-process printing rustfix does to sync output because Windows’ stdout isn’t line buffered(we spawn a TCP server that accepts diagnostic messages and prints them)
Prior art and thoughts
Pascal’s ideas for a CLI-focused MVP
Pitch
What to do
Further steps
Interesting test cases