Construct and execute multiple concurrent forks of the chain.

    Any number of forks may be executed.  For each fork, provide an iterable of
    commands.

    Returns the resulting chain objects for each fork.


    .. code-block:: python

        chain_a, chain_b = build(
            mining_chain,
            chain_split(
                (mine_block(extra_data=b'chain-a'), mine_block()),
                (mine_block(extra_data=b'chain-b'), mine_block(), mine_block()),
            ),
        )

def chain_split(*splits: Iterable[Callable[..., Any]]) -> Callable[[BaseChain], Iterable[BaseChain]]:   # noqa: E501
    """
    Construct and execute multiple concurrent forks of the chain.

    Any number of forks may be executed.  For each fork, provide an iterable of
    commands.

    Returns the resulting chain objects for each fork.


    .. code-block:: python

        chain_a, chain_b = build(
            mining_chain,
            chain_split(
                (mine_block(extra_data=b'chain-a'), mine_block()),
                (mine_block(extra_data=b'chain-b'), mine_block(), mine_block()),
            ),
        )
    """
    if not splits:
        raise ValidationError("Cannot use `chain_split` without providing at least one split")

    @functools.wraps(chain_split)
    @to_tuple
    def _chain_split(chain: BaseChain) -> Iterable[BaseChain]:
        for split_fns in splits:
            result = build(
                chain,
                *split_fns,
            )
            yield result

    return _chain_split