typeshare_driver/lib.rs
1/*!
2Framework for creating a typeshare binary.
3
4This library provides a macro that creates a `fn main` that implements an
5entire typeshare binary, using only the [Language](https://docs.rs/typeshare-model/latest/typeshare_model/trait.Language.html)
6implementations that you provide.
7
8The macro is very simple. Supposing that you have implementations of `Language`
9called `Kotlin` and `Swift`, call the macro like this:
10
11```ignore
12use std::marker::PhantomData;
13use typeshare_driver::typeshare_binary;
14
15struct Kotlin {}
16
17// impl<'config> Language<'config> for Kotlin { ... }
18
19struct Swift<'c> {
20 config: PhantomData<&'config str>;
21}
22
23// impl<'config> Language<'config> for Swift<'config> { ... }
24
25typeshare_binary! { Kotlin, Swift<'config> }
26```
27
28This creates an `fn main` that uses the functionality in [typeshare-engine][typeshare_engine]
29to create a complete, working typeshare binary. That binary will include a
30complete command-line interface, populated with global options like `--config`
31and `--lang`, as well as language-specific options like `--kotlin-package`;
32these language-specific flags are determined automatically based on the
33[`Config`](https://docs.rs/typeshare-model/latest/typeshare_model/trait.Language.html#associatedtype.Config)
34type provided by each `Language` implementation. Use `--help` for a complete
35description of all CLI options.
36
37See the [`typeshare_model::Language`](https://docs.rs/typeshare-model/latest/typeshare_model/trait.Language.html)
38docs for details on how to create a specific language implementation.
39
40See the [typeshare-engine][typeshare_engine] docs if you want to use typeshare
41as a library instead of a binary program; it contains all of the actual logic
42for *running* typeshare. typeshare-driver just bootstraps the functionality
43in the engine into a working `main`.
44*/
45
46#[doc(hidden)]
47pub mod ඞ {
48 pub use ::anyhow;
49 pub use ::typeshare_engine as engine;
50}
51
52#[doc(hidden)]
53#[macro_export]
54macro_rules! type_lifetime_helper {
55 ($lt:lifetime, $Language:ident) => {$Language};
56 ($lt:lifetime, $Language:ident < $lt2:lifetime >) => {$Language<$lt>};
57}
58
59/**
60Macro that creates an `fn main` with a complete typeshare program, based on
61the `Language` implementations provided. See the [crate docs][crate] for
62details and an example.
63*/
64#[macro_export]
65macro_rules! typeshare_binary {
66 ($($Language:ident $(< $config:lifetime >)?),+ $(,)?) => {
67 fn main() -> $crate::ඞ::anyhow::Result<()> {
68 struct Local;
69
70 impl $crate::ඞ::engine::driver::LanguageHelper for Local {
71 type LanguageSet<'config> = ($(
72 $crate::type_lifetime_helper! ('config, $Language $(<$config>)?),
73 )+);
74 }
75
76 $crate::ඞ::engine::driver::main_body::<Local>(
77 $crate::ඞ::engine::args::PersonalizeClap::new()
78 .name(env!("CARGO_PKG_NAME"))
79 .version(env!("CARGO_PKG_VERSION")),
80 )
81 }
82 };
83}