Setup
Mingling's Basic Components
---
## Usage
`Setup` is used to organize and package the initialization process of a `Program`, making the project easier to manage. It is defined as follows:
```rust
struct MySetup;
impl ProgramSetup
for MySetup
{
fn setup(
&mut self,
program: &mut Program
) {
// Your setup logic
}
}
```
For example:
```rust
use std::{env::current_dir, path::PathBuf};
use mingling::{
Program,
macros::{dispatcher, gen_program, renderer},
setup::ProgramSetup,
};
// Global state
static OUTPUT_PATH: std::sync::OnceLock
= std::sync::OnceLock::new();
fn main() {
let mut program = ThisProgram::new();
program.with_setup(MySetup);
program.exec();
}
// Define two Dispatchers using `dispatcher!`
dispatcher!("member.add",
AddMemberCommand => AddMemberEntry);
dispatcher!("member.rm",
RemoveMemberCommand => RemoveMemberEntry);
struct MySetup;
impl ProgramSetup for MySetup {
fn setup(
&mut self, program: &mut Program
) {
// Register Dispatchers
program.with_dispatcher(AddMemberCommand);
program.with_dispatcher(RemoveMemberCommand);
// Initialize global output once
OUTPUT_PATH.get_or_init(|| current_dir().unwrap());
// Pick the "--quiet" or "-q" flag
program.global_flag(["--quiet", "-q"], |p| {
// Disable render output
p.stdout_setting.render_output = false;
});
// Pick the "--output" or "-O" flag, write to output
program.global_argument(["--output", "-O"], |_, v| {
let _ = OUTPUT_PATH.set(PathBuf::from(v));
});
}
}
// Define empty renderer types to give the two types type IDs
#[renderer]
fn phantom_renderer_add_member(
_prev: AddMemberEntry
) {}
#[renderer]
fn phantom_renderer_remove_member(
_prev: RemoveMemberEntry
) {}
gen_program!();
```
## Simplified Syntax
If you find the above declaration method too **verbose**, you can use the `program_setup!` macro to simplify it. The format is:
```rust
#[program_setup]
fn my_setup(
program: &mut Program
) {
// Your setup logic
}
```
For example:
```rust
use std::{env::current_dir, path::PathBuf};
use mingling::{
Program,
macros::{
dispatcher,
gen_program,
program_setup,
renderer
},
};
static OUTPUT_PATH: std::sync::OnceLock
= std::sync::OnceLock::new();
#[tokio::main]
async fn main() {
let mut program = ThisProgram::new();
program.with_setup(MySetup);
program.exec().await;
}
dispatcher!("member.add",
AddMemberCommand => AddMemberEntry);
dispatcher!("member.rm",
RemoveMemberCommand => RemoveMemberEntry);
#[program_setup]
fn my_setup(
program: &mut Program
) {
program.with_dispatcher(AddMemberCommand);
program.with_dispatcher(RemoveMemberCommand);
OUTPUT_PATH.get_or_init(|| current_dir().unwrap());
program.global_flag(["--quiet", "-q"], |p| {
p.stdout_setting.render_output = false;
});
program.global_argument(["--output", "-O"], |_, v| {
let _ = OUTPUT_PATH.set(PathBuf::from(v));
});
}
#[renderer]
fn phantom_renderer_add_member(
_prev: AddMemberEntry
) {}
#[renderer]
fn phantom_renderer_remove_member(
_prev: RemoveMemberEntry
) {}
gen_program!();
```
## 💡 Next Page
> **Basic Component** - Dispatcher [Go](./pages/2-basic/3-dispatcher)