Repository: bevyengine/bevy
File: crates/bevy_ecs/src/schedule/condition.rs (Rust)

Code before:
pub type Nor<A, B> = CombinatorSystem<NorMarker, A, B>;

/// Combines the outputs of two systems using the `||` operator.
pub type Or<A, B> = CombinatorSystem<OrMarker, A, B>;

/// Combines and inverts the outputs of two systems using the `^` and `!` operators.
pub type Xnor<A, B> = CombinatorSystem<XnorMarker, A, B>;

/// Combines the outputs of two systems using the `^` operator.
pub type Xor<A, B> = CombinatorSystem<XorMarker, A, B>;

#[doc(hidden)]
pub struct AndMarker;

impl<In, A, B> Combine<A, B> for AndMarker
where
    for<'a> In: SystemInput<Inner<'a>: Copy>,
    A: System<In = In, Out = bool>,
    B: System<In = In, Out = bool>,
{
    type In = In;
    type Out = bool;

    fn combine<T>(
        input: <Self::In as SystemInput>::Inner<'_>,
        mut data: T,
        a: impl FnOnce(SystemIn<'_, A>, &mut T) -> Result<A::Out, RunSystemError>,
        b: impl FnOnce(SystemIn<'_, A>, &mut T) -> Result<B::Out, RunSystemError>,
    ) -> Result<Self::Out, RunSystemError> {
        Ok(a(input, &mut data)? && b(input, &mut data)?)
    }
}

#[doc(hidden)]
pub struct NandMarker;

impl<In, A, B> Combine<A, B> for NandMarker
where
    for<'a> In: SystemInput<Inner<'a>: Copy>,
    A: System<In = In, Out = bool>,
    B: System<In = In, Out = bool>,
{
    type In = In;
    type Out = bool;

    fn combine<T>(
        input: <Self::In as SystemInput>::Inner<'_>,
        mut data: T,
        a: impl FnOnce(SystemIn<'_, A>, &mut T) -> Result<A::Out, RunSystemError>,
        b: impl FnOnce(SystemIn<'_, A>, &mut T) -> Result<B::Out, RunSystemError>,
    ) -> Result<Self::Out, RunSystemError> {

Review comment (suggestion):
While I don't see us using this in a way that currently requires it, I'm much more comfortable with this taking a `&mut T` instead of taking ownership, as it'd force any `T: Drop` to invoke it here or have an overly generic `mem::forget` in those cases.

Code after:
pub type Nor<A, B> = CombinatorSystem<NorMarker, A, B>;

/// Combines the outputs of two systems using the `||` operator.
pub type Or<A, B> = CombinatorSystem<OrMarker, A, B>;

/// Combines and inverts the outputs of two systems using the `^` and `!` operators.
pub type Xnor<A, B> = CombinatorSystem<XnorMarker, A, B>;

/// Combines the outputs of two systems using the `^` operator.
pub type Xor<A, B> = CombinatorSystem<XorMarker, A, B>;

#[doc(hidden)]
pub struct AndMarker;

impl<In, A, B> Combine<A, B> for AndMarker
where
    for<'a> In: SystemInput<Inner<'a>: Copy>,
    A: System<In = In, Out = bool>,
    B: System<In = In, Out = bool>,
{
    type In = In;
    type Out = bool;

    fn combine<T>(
        input: <Self::In as SystemInput>::Inner<'_>,
        data: &mut T,
        a: impl FnOnce(SystemIn<'_, A>, &mut T) -> Result<A::Out, RunSystemError>,
        b: impl FnOnce(SystemIn<'_, A>, &mut T) -> Result<B::Out, RunSystemError>,
    ) -> Result<Self::Out, RunSystemError> {
        Ok(a(input, data)? && b(input, data)?)
    }
}

#[doc(hidden)]
pub struct NandMarker;

impl<In, A, B> Combine<A, B> for NandMarker
where
    for<'a> In: SystemInput<Inner<'a>: Copy>,
    A: System<In = In, Out = bool>,
    B: System<In = In, Out = bool>,
{
    type In = In;
    type Out = bool;

    fn combine<T>(
        input: <Self::In as SystemInput>::Inner<'_>,
        data: &mut T,
        a: impl FnOnce(SystemIn<'_, A>, &mut T) -> Result<A::Out, RunSystemError>,
        b: impl FnOnce(SystemIn<'_, A>, &mut T) -> Result<B::Out, RunSystemError>,
    ) -> Result<Self::Out, RunSystemError> {