Alright, I will settle with this for now 👍 (feel free to merge it)
I leave it here just for future references
I have tried to create another builder pattern in another project but it seems I can't get it applied in here. I use trait and and dynamic dispatch to get it works. Here is how I do it:
1. [Define the config field](https://github.com/DrSensor/scdlang/blob/15d1c6652f69e0dd86628cba1f2db6384740a779/packages/core/src/core/builder.rs#L30-L36)
```rust
pub struct Scdlang<'g> {
pub(crate) path: Option<&'g str>,
pub(crate) line: Option,
pub(super) clear_cache: bool, //-|in case for program that need to disable…|
pub(super) semantic_error: bool, //-|…then enable semantic error at runtime|
}
```
2. [Define the `Builder` trait](https://github.com/DrSensor/scdlang/blob/15d1c6652f69e0dd86628cba1f2db6384740a779/packages/core/src/external.rs#L97-L111)
```rust
pub trait Builder<'t> {
/** Automatically clear cache when out of scope.
* `default` - set `false` to disable it. (default: `true`)
The cache is used for analyzing semantics error.
This can be handy when parsing in streaming fashion. */
fn auto_clear_cache(&mut self, default: bool) -> &mut dyn Builder<'t>;
/// Enable semantics error. (default: `true`).
fn with_err_semantic(&mut self, default: bool) -> &mut dyn Builder<'t>;
/// Set path that going to be printed in the error essages.
fn with_err_path(&mut self, path: &'t str) -> &mut dyn Builder<'t>;
/// Set the line_of_code offset of the error essages.
fn with_err_line(&mut self, line: usize) -> &mut dyn Builder<'t>;
}
```
3. [Implement the `Builder` trait](https://github.com/DrSensor/scdlang/blob/15d1c6652f69e0dd86628cba1f2db6384740a779/packages/core/src/core/builder.rs#L60-L80)
```rust
impl<'g> Builder<'g> for Scdlang<'g> {
fn with_err_path(&mut self, path: &'g str) -> &mut dyn Builder<'g> {
self.path = Some(path);
self
}
fn with_err_line(&mut self, line: usize) -> &mut dyn Builder<'g> {
self.line = Some(line);
self
}
fn with_err_semantic(&mut self, default: bool) -> &mut dyn Builder<'g> {
self.semantic_error = default;
self
}
fn auto_clear_cache(&mut self, default: bool) -> &mut dyn Builder<'g> {
self.clear_cache = default;
self
}
}
```
4. [dynamic dispatch](https://github.com/DrSensor/scdlang/blob/15d1c6652f69e0dd86628cba1f2db6384740a779/packages/core/src/external.rs#L81)
```rust
fn configure(&mut self) -> &mut dyn Builder<'t>;
```
5. [make struct that implement `Builder` trait as a _member_ of another struct](https://github.com/DrSensor/scdlang/blob/15d1c6652f69e0dd86628cba1f2db6384740a779/packages/transpiler/xstate/src/asg/mod.rs#L24-L31)
```rust
pub struct Machine<'a> {
#[serde(skip)]
builder: Scdlang<'a>,
#[serde(flatten)]
schema: StateChart, // TODO: replace with 👇 when https://github.com/serde-rs/serde/issues/1507 resolved
// schema: mem::ManuallyDrop,
}
```
6. [Implement `configure` function in struct that have `Builder` trait as a member](https://github.com/DrSensor/scdlang/blob/15d1c6652f69e0dd86628cba1f2db6384740a779/packages/transpiler/xstate/src/asg/mod.rs#L34-L36)
```rust
fn configure(&mut self) -> &mut Builder<'a> {
&mut self.builder
}
```