orchestra

The orchestra pattern is a partial actor pattern, with a global orchestrator regarding relevant work items.

proc-macro

The proc macro provides a convenience generator with a builder pattern, where at it's core it creates and spawns a set of subsystems, which are purely declarative.

```rust #[orchestra(signal=SigSigSig, event=Event, gen=AllMessages, error=OrchestraError)] pub struct Opera { #[subsystem(MsgA, sends: [MsgB])] sub_a: AwesomeSubSysA,

    #[subsystem(MsgB, sends: [MsgA])]
    sub_b: AwesomeSubSysB,
}

```

```rust /// Execution context, always required. pub struct DummyCtx;

/// Task spawner, always required
/// and must implement `trait orchestra::Spawner`.
pub struct DummySpawner;

fn main() {
    let _orchestra = Opera::builder()
        .sub_a(AwesomeSubSysA::default())
        .sub_b(AwesomeSubSysB::default())
        .spawner(DummySpawner)
        .build();
}

```

In the shown main, the orchestra is created by means of a generated, compile time erroring builder pattern.

The builder requires all subsystems, baggage fields (additional struct data) and spawner to be set via the according setter method before build method could even be called. Failure to do such an initialization will lead to a compile error. This is implemented by encoding each builder field in a set of so called state generics, meaning that each field can be either Init<T> or Missing<T>, so each setter translates a state from Missing to Init state for the specific struct field. Therefore, if you see a compile time error that blames about Missing where Init is expected it usually means that some subsystems or baggage fields were not set prior to the build call.

To exclude subsystems from such a check, one can set wip attribute on some subsystem that is not ready to be included in the Orchestra:

```rust #[orchestra(signal=SigSigSig, event=Event, gen=AllMessages, error=OrchestraError)] pub struct Opera { #[subsystem(MsgA, sends: MsgB)] sub_a: AwesomeSubSysA,

    #[subsystem(MsgB, sends: MsgA), wip]
    sub_b: AwesomeSubSysB, // This subsystem will not be required nor allowed to be set
}

```

Baggage fields can be initialized more than one time, however, it is not true for subsystems: subsystems must be initialized only once (another compile time check) or be replaced by a special setter like method replace_<subsystem>.

A task spawner and subsystem context are required to be defined with Spawner and respectively SubsystemContext implemented.

Debugging

As always, debugging is notoriously annoying with bugged proc-macros.

Therefore expander is employed to yield better error messages. Enable with --feature=orchestra/expand.

License

Licensed under either of

at your option.