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}