Skip to main content

commerce_theory/
lib.rs

1//! Runtime Rust mirror of the `CommerceTheory` Lean package.
2//!
3//! The Lean package stores proof fields in validated records. This crate mirrors
4//! those records with private fields, smart constructors, executable predicates,
5//! and tests that exercise the same safety guarantees at runtime.
6
7#![forbid(unsafe_code)]
8#![allow(clippy::too_many_arguments)]
9
10#[doc(hidden)]
11pub trait FieldAccess {
12    type Output<'a>
13    where
14        Self: 'a;
15
16    fn access(&self) -> Self::Output<'_>;
17}
18
19#[doc(hidden)]
20pub trait RefFieldAccess {}
21
22impl<T: RefFieldAccess> FieldAccess for T {
23    type Output<'a>
24        = &'a Self
25    where
26        Self: 'a;
27
28    fn access(&self) -> Self::Output<'_> {
29        self
30    }
31}
32
33impl FieldAccess for String {
34    type Output<'a> = &'a str;
35
36    fn access(&self) -> Self::Output<'_> {
37        self
38    }
39}
40
41impl<T> FieldAccess for Vec<T> {
42    type Output<'a>
43        = &'a [T]
44    where
45        T: 'a;
46
47    fn access(&self) -> Self::Output<'_> {
48        self
49    }
50}
51
52impl<T: Copy> FieldAccess for Option<T> {
53    type Output<'a>
54        = Self
55    where
56        T: 'a;
57
58    fn access(&self) -> Self::Output<'_> {
59        *self
60    }
61}
62
63macro_rules! impl_copy_field_access {
64    ($($ty:ty),* $(,)?) => {
65        $(
66            impl $crate::FieldAccess for $ty {
67                type Output<'a> = Self;
68
69                fn access(&self) -> Self::Output<'_> {
70                    *self
71                }
72            }
73        )*
74    };
75}
76
77macro_rules! impl_ref_field_access {
78    ($($ty:ty),* $(,)?) => {
79        $(
80            impl $crate::RefFieldAccess for $ty {}
81        )*
82    };
83}
84
85impl_copy_field_access!(
86    bool,
87    u128,
88    i128,
89    time::Date,
90    time::Duration,
91    time::PrimitiveDateTime,
92);
93
94macro_rules! field_getter {
95    ($field:ident : $ty:ty) => {
96        #[must_use]
97        pub fn $field(&self) -> <$ty as $crate::FieldAccess>::Output<'_> {
98            <$ty as $crate::FieldAccess>::access(&self.$field)
99        }
100    };
101}
102
103macro_rules! domain_struct {
104    ($(#[$meta:meta])* $vis:vis struct $name:ident { $($field:ident : $ty:ty),* $(,)? }) => {
105        $(#[$meta])*
106        #[derive(Clone, Debug, PartialEq, Eq)]
107        #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
108        $vis struct $name {
109            $(pub(crate) $field: $ty),*
110        }
111
112        impl $name {
113            #[must_use]
114            pub const fn new($($field: $ty),*) -> Self {
115                Self { $($field),* }
116            }
117
118            pub const fn try_new($($field: $ty),*) -> Result<Self, $crate::foundation::ValidationError> {
119                Ok(Self::new($($field),*))
120            }
121
122            $(
123                field_getter!($field: $ty);
124            )*
125        }
126
127        impl $crate::RefFieldAccess for $name {}
128    };
129}
130
131macro_rules! impl_getters {
132    ($name:ident { $($field:ident : $ty:ty),* $(,)? }) => {
133        impl $name {
134            $(
135                field_getter!($field: $ty);
136            )*
137        }
138    };
139}
140
141pub mod accounting;
142pub mod b2b;
143pub mod basic;
144pub mod catalog;
145pub mod competitor_pricing;
146pub mod crm;
147pub mod dropship_profit;
148pub mod dropshipping;
149pub mod event_language;
150pub mod event_replay;
151pub mod event_sourcing;
152pub mod forecasting;
153pub mod foundation;
154pub mod fulfillment_finance;
155pub mod implicit_invariants;
156pub mod inventory;
157pub mod inventory_algorithms;
158pub mod keyed_totals;
159pub mod logistics;
160pub mod marketing;
161pub mod marketplace;
162pub mod merchandising;
163pub mod opportunity_portfolio;
164pub mod opportunity_ranking;
165pub mod orders;
166pub mod post_purchase;
167pub mod pricing;
168pub mod risk_privacy;
169pub mod summary;
170pub mod tax;
171pub mod validation;
172pub mod workflow;
173
174pub use accounting::*;
175pub use b2b::*;
176pub use basic::*;
177pub use catalog::*;
178pub use competitor_pricing::*;
179pub use crm::*;
180pub use dropship_profit::*;
181pub use dropshipping::*;
182pub use event_language::*;
183pub use event_replay::*;
184pub use event_sourcing::*;
185pub use forecasting::*;
186pub use foundation::*;
187pub use fulfillment_finance::*;
188pub use implicit_invariants::*;
189pub use inventory::*;
190pub use inventory_algorithms::*;
191pub use keyed_totals::*;
192pub use logistics::*;
193pub use marketing::*;
194pub use marketplace::*;
195pub use merchandising::*;
196pub use opportunity_portfolio::*;
197pub use opportunity_ranking::*;
198pub use orders::*;
199pub use post_purchase::*;
200pub use pricing::*;
201pub use risk_privacy::*;
202pub use tax::*;
203pub use validation::*;
204pub use workflow::*;
205
206#[cfg(test)]
207mod coverage_anchor_tests {
208    use super::*;
209
210    #[test]
211    fn crate_private_anchor_functions_are_covered() {
212        let stock = StockState::try_new(Sku::new(1), 1, 0).unwrap();
213
214        crate::b2b::_marketing_anchor(None);
215        crate::dropship_profit::_dropshipping_anchor(None);
216        crate::dropshipping::_b2b_anchor(None);
217        crate::event_sourcing::_risk_anchor(None);
218        crate::forecasting::_post_purchase_anchor(None);
219        crate::fulfillment_finance::_merchandising_anchor(None);
220        crate::merchandising::_competitor_anchor(None);
221        crate::opportunity_portfolio::_forecasting_anchor(None);
222        crate::post_purchase::_event_anchor(None);
223        crate::pricing::_inventory_anchor(&stock);
224    }
225}
226
227impl_copy_field_access!(
228    AccountTier,
229    Action,
230    AccessPurpose,
231    AdDestination,
232    AdPlatform,
233    AdType,
234    CampaignStatus,
235    CanOrderTransition,
236    CompetitivePricingStrategy,
237    Confidence,
238    ConsentPurpose,
239    ConsentStatus,
240    ContactKind,
241    Currency,
242    CustomerKind,
243    CRMAccountStatus,
244    DataCategory,
245    DropshipPOStatus,
246    DropshipPOTransitionLabel,
247    ErasureStatus,
248    InteractionKind,
249    LeadStatus,
250    ListingStatus,
251    LogisticsExceptionKind,
252    Marketplace,
253    OpportunityStage,
254    OrderEventSymbol,
255    OrderEventValidationState,
256    OrderStatus,
257    OrderTransitionLabel,
258    PaymentState,
259    PaymentTerms,
260    PostingSide,
261    ProcessingBasis,
262    ProductStatus,
263    PromotionStackingPolicy,
264    ReservationStatus,
265    ReturnAuthorizationStatus,
266    Role,
267    RoundingMode,
268    SalesChannel,
269    SerialNumber,
270    ShipmentStatus,
271    SubscriptionLifecycleStatus,
272    SubscriptionStatus,
273    SupplierReservationStatus,
274    SupportCaseStatus,
275    SupportPriority,
276    TaxPriceMode,
277    TaxRegime,
278    TaxTreatment,
279    TrackingEventKind,
280    TradeMode,
281    TrustLevel,
282    ValidationError,
283    Lead,
284    SalesOpportunity,
285    StockState,
286    SupportCase,
287    TimedReservation,
288    VersionedStock,
289);
290
291impl<T> RefFieldAccess for Timed<T> {}
292
293impl<S: OrderStatusMarker> FieldAccess for TypedOrder<S> {
294    type Output<'a>
295        = Self
296    where
297        S: 'a;
298
299    fn access(&self) -> Self::Output<'_> {
300        *self
301    }
302}
303
304impl<S: PaymentStateMarker> FieldAccess for TypedPayment<S> {
305    type Output<'a>
306        = Self
307    where
308        S: 'a;
309
310    fn access(&self) -> Self::Output<'_> {
311        *self
312    }
313}
314
315impl_ref_field_access!(
316    AcceptedPromotionSet,
317    ActiveCRMAccount,
318    ApprovedOrderableSupplierQuality,
319    ApprovedSupplierQuality,
320    AuditedCommand,
321    AuditedDataAccess,
322    AuditedEntityCommand,
323    BackorderRequest,
324    B2BTaxExemption,
325    BalancedJournalEntry,
326    BrandPricingPolicy,
327    BoundedCouponApplication,
328    BundleComponent,
329    BundleReservation,
330    CapturedPaymentJournalProjection,
331    CapturedPaymentMatchesOrder,
332    CarrierHandoff,
333    CarrierQuote,
334    CartLine,
335    CashflowPlan,
336    ChannelPricePolicy,
337    Chargeback,
338    ChargebackForCapturedPayment,
339    ClickAttributedCampaign,
340    CompetitorAwareDropshipOffer,
341    CompetitorPriceBenchmark,
342    ConcurrentReservationConflict,
343    ConvertedLeadOpportunity,
344    CRMAccount,
345    CRMAccountContact,
346    CRMApprovedReturnHandling,
347    CRMInteraction,
348    CRMInteractionForContact,
349    CRMOrderContact,
350    CustomerSegment,
351    DeliveredShipment,
352    DeliveryPromise,
353    DistinctFulfillmentPlan,
354    DomainEvent,
355    DropshipCostUpperBounds,
356    DropshipFulfillment,
357    DropshipLine,
358    DropshipOpportunityCandidate,
359    DropshipOpportunityPortfolio,
360    DropshipOffer,
361    DropshipPurchaseOrder,
362    DropshipReturnRequest,
363    EventBackedCashflowPlan,
364    Experiment,
365    ExperimentVariant,
366    ExchangeRate,
367    FreshCurrencyConversion,
368    FraudCheckedCouponApplication,
369    Funnel,
370    GiftCardRedemption,
371    GuaranteedDropshipProfitQuote,
372    LeadForContact,
373    LogisticsExceptionSupportCase,
374    LogisticsShipment,
375    LogisticsShipmentPlan,
376    MapCompliantCompetitorAwareOffer,
377    MarketplaceFacilitatorTax,
378    MarketplaceFeeLedger,
379    MarketplaceOrder,
380    MarketplacePayoutCalculation,
381    MarketingCampaign,
382    MatchedOrderAttributionLedger,
383    Order,
384    OrderAttributionLedger,
385    OrderTaxInvoiceLink,
386    OpportunityForContact,
387    PaymentLedger,
388    PermittedAccountMessage,
389    PermittedCustomerMessage,
390    PickTask,
391    PreorderReservation,
392    PreorderWindow,
393    ProductCatalogEntry,
394    PublishableFeedLine,
395    ReconciliationWithinTolerance,
396    RecurringSubscription,
397    RefundJournalProjection,
398    ReservedDropshipLine,
399    ReservationAttempt,
400    ResolvedSupportCase,
401    RetainedPersonalData,
402    RetentionOffer,
403    RetailLine,
404    ReturnAuthorization,
405    ReturnReceipt,
406    SalesPipeline,
407    SafeProductFeedLine,
408    SellableCatalogEntry,
409    SegmentMembership,
410    SerializedInventorySet,
411    ShipmentForCRMOrder,
412    SkuSubstitution,
413    SourceableDistributorProduct,
414    SplitFulfillmentPlan,
415    SubscriptionPlan,
416    SupplierDailyCapacity,
417    SupplierReservation,
418    SupportCaseForContact,
419    SyncedMarketplaceListing,
420    TaxCalculation,
421    TaxExclusivePrice,
422    TaxExemptionCertificate,
423    TaxInclusivePrice,
424    TaxInvoice,
425    TaxInvoiceLine,
426    TrackingHistory,
427    TradePriceBookEntry,
428    TrustedFreshCompetitorBenchmark,
429    ValidEventStream,
430    ValidGiftCardRedemptionAt,
431    ValidListingContent,
432    ValidRefund,
433    ValidSearchResultItem,
434    WarehouseShipment,
435    WarehouseTransfer,
436    WholesaleCreditAccount,
437    WholesaleCreditCheckout,
438    WholesaleLine,
439);