Skip to main content

axiolid_core/
operation.rs

1//! Small operation values shared by representation and algorithm contracts.
2
3/// Regularized boolean set operation on solids.
4///
5/// The operand set matches `axiolid-overlay`'s planar contract so 2D and 3D
6/// booleans describe the same algebra. It is deliberately *not* a mirror of any
7/// one backend's operation enum: `SymmetricDifference` exists here because the
8/// set algebra has it, not because a provider offered it.
9///
10/// Marked `#[non_exhaustive]` so a future operand cannot break downstream
11/// `match` arms.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
13#[non_exhaustive]
14#[cfg_attr(
15    feature = "serde",
16    derive(serde::Serialize, serde::Deserialize),
17    serde(deny_unknown_fields)
18)]
19pub enum BooleanOperator {
20    /// Points in either operand.
21    Union,
22    /// Points in both operands.
23    Intersection,
24    /// Ordered: points in the subject and not in the tool.
25    Difference,
26    /// Points in exactly one operand, equal to `(A ∪ B) \ (A ∩ B)`.
27    SymmetricDifference,
28}
29
30impl BooleanOperator {
31    /// Every operand in a stable, declared order.
32    ///
33    /// Conformance suites iterate this so a new operand is automatically
34    /// covered rather than silently untested.
35    pub const ALL: [Self; 4] = [
36        Self::Union,
37        Self::Intersection,
38        Self::Difference,
39        Self::SymmetricDifference,
40    ];
41
42    /// Whether swapping the operands leaves the result unchanged.
43    ///
44    /// `Difference` is the only ordered operand; the identity is part of the
45    /// public contract because callers rely on it to reorder work.
46    pub const fn is_commutative(self) -> bool {
47        !matches!(self, Self::Difference)
48    }
49}