lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README | LICENSE

commit fd9328852cfa9248be8657e809c0d0c77888271f
parent b66766d5f17edace164401a4a31fc3bf364208b7
Author: triesap <tyson@radroots.org>
Date:   Sun, 22 Feb 2026 14:20:12 +0000

trade: consolidate listing kind lane around dvm kinds


- replace duplicated trade listing kind families with one canonical set
- rewire trade envelope and app runtime imports to listing kinds constants
- remove legacy listing meta and stage modules tied to old kind values
- assert message type kind mappings stay inside the canonical kind set

Diffstat:
Mcrates/app-core/src/runtime/trade_listing.rs | 4++--
Mcrates/trade/src/listing/dvm.rs | 5+++--
Dcrates/trade/src/listing/dvm_kinds.rs | 162-------------------------------------------------------------------------------
Mcrates/trade/src/listing/kinds.rs | 242++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Dcrates/trade/src/listing/meta.rs | 452-------------------------------------------------------------------------------
Mcrates/trade/src/listing/mod.rs | 12------------
Dcrates/trade/src/listing/stage/accept.rs | 23-----------------------
Dcrates/trade/src/listing/stage/conveyance.rs | 48------------------------------------------------
Dcrates/trade/src/listing/stage/fulfillment.rs | 42------------------------------------------
Dcrates/trade/src/listing/stage/invoice.rs | 26--------------------------
Dcrates/trade/src/listing/stage/order.rs | 41-----------------------------------------
Dcrates/trade/src/listing/stage/payment.rs | 38--------------------------------------
Dcrates/trade/src/listing/stage/receipt.rs | 23-----------------------
13 files changed, 146 insertions(+), 972 deletions(-)

diff --git a/crates/app-core/src/runtime/trade_listing.rs b/crates/app-core/src/runtime/trade_listing.rs @@ -25,7 +25,7 @@ use radroots_trade::listing::{ TradeListingEnvelope, TradeListingMessagePayload, TradeListingMessageType, TradeListingValidateRequest, }, - dvm_kinds::TRADE_LISTING_DVM_KINDS, + kinds::TRADE_LISTING_KINDS, order::{TradeOrder, TradeOrderItem, TradeOrderStatus}, tags::trade_listing_dvm_tags, validation::{RadrootsTradeListing, validate_listing_event}, @@ -295,7 +295,7 @@ impl RadrootsRuntime { .as_ref() .ok_or_else(|| RadrootsAppError::Msg("nostr not initialized".into()))?; - let kinds: Vec<RadrootsNostrKind> = TRADE_LISTING_DVM_KINDS + let kinds: Vec<RadrootsNostrKind> = TRADE_LISTING_KINDS .iter() .map(|k| RadrootsNostrKind::Custom(*k)) .collect(); diff --git a/crates/trade/src/listing/dvm.rs b/crates/trade/src/listing/dvm.rs @@ -8,7 +8,7 @@ use radroots_events_codec::d_tag::is_d_tag_base64url; #[cfg(feature = "ts-rs")] use ts_rs::TS; -use crate::listing::dvm_kinds::{ +use crate::listing::kinds::{ KIND_TRADE_LISTING_ANSWER_RES, KIND_TRADE_LISTING_CANCEL_REQ, KIND_TRADE_LISTING_DISCOUNT_ACCEPT_REQ, KIND_TRADE_LISTING_DISCOUNT_DECLINE_REQ, KIND_TRADE_LISTING_DISCOUNT_OFFER_RES, KIND_TRADE_LISTING_DISCOUNT_REQ, @@ -455,6 +455,7 @@ mod tests { #[test] fn message_type_kind_and_request_flags_cover_all_variants() { + let expected_kinds = crate::listing::kinds::TRADE_LISTING_KINDS; let cases = [ (TradeListingMessageType::ListingValidateRequest, true, false), (TradeListingMessageType::ListingValidateResult, false, true), @@ -477,7 +478,7 @@ mod tests { for (message_type, is_request, is_result) in cases { assert_eq!(message_type.is_request(), is_request); assert_eq!(message_type.is_result(), is_result); - assert!(message_type.kind() > 0); + assert!(expected_kinds.contains(&message_type.kind())); } } diff --git a/crates/trade/src/listing/dvm_kinds.rs b/crates/trade/src/listing/dvm_kinds.rs @@ -1,162 +0,0 @@ -#![forbid(unsafe_code)] - -#[cfg(feature = "ts-rs")] -use ts_rs::TS; - -pub const KIND_TRADE_LISTING_VALIDATE_REQ: u16 = 5321; -pub const KIND_TRADE_LISTING_VALIDATE_RES: u16 = 6321; - -pub const KIND_TRADE_LISTING_ORDER_REQ: u16 = 5322; -pub const KIND_TRADE_LISTING_ORDER_RES: u16 = 6322; - -pub const KIND_TRADE_LISTING_ORDER_REVISION_REQ: u16 = 5323; -pub const KIND_TRADE_LISTING_ORDER_REVISION_RES: u16 = 6323; - -pub const KIND_TRADE_LISTING_QUESTION_REQ: u16 = 5324; -pub const KIND_TRADE_LISTING_ANSWER_RES: u16 = 6324; - -pub const KIND_TRADE_LISTING_DISCOUNT_REQ: u16 = 5325; -pub const KIND_TRADE_LISTING_DISCOUNT_OFFER_RES: u16 = 6325; - -pub const KIND_TRADE_LISTING_DISCOUNT_ACCEPT_REQ: u16 = 5326; -pub const KIND_TRADE_LISTING_DISCOUNT_DECLINE_REQ: u16 = 5327; - -pub const KIND_TRADE_LISTING_CANCEL_REQ: u16 = 5328; -pub const KIND_TRADE_LISTING_FULFILLMENT_UPDATE_REQ: u16 = 5329; -pub const KIND_TRADE_LISTING_RECEIPT_REQ: u16 = 5330; - -pub const TRADE_LISTING_DVM_KINDS: [u16; 15] = [ - KIND_TRADE_LISTING_VALIDATE_REQ, - KIND_TRADE_LISTING_VALIDATE_RES, - KIND_TRADE_LISTING_ORDER_REQ, - KIND_TRADE_LISTING_ORDER_RES, - KIND_TRADE_LISTING_ORDER_REVISION_REQ, - KIND_TRADE_LISTING_ORDER_REVISION_RES, - KIND_TRADE_LISTING_QUESTION_REQ, - KIND_TRADE_LISTING_ANSWER_RES, - KIND_TRADE_LISTING_DISCOUNT_REQ, - KIND_TRADE_LISTING_DISCOUNT_OFFER_RES, - KIND_TRADE_LISTING_DISCOUNT_ACCEPT_REQ, - KIND_TRADE_LISTING_DISCOUNT_DECLINE_REQ, - KIND_TRADE_LISTING_CANCEL_REQ, - KIND_TRADE_LISTING_FULFILLMENT_UPDATE_REQ, - KIND_TRADE_LISTING_RECEIPT_REQ, -]; - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr( - feature = "ts-rs", - ts( - export, - export_to = "types.ts", - rename_all = "SCREAMING_SNAKE_CASE", - repr(enum) - ) -)] -#[repr(u16)] -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub enum TradeListingDvmKind { - KindTradeListingValidateReq = KIND_TRADE_LISTING_VALIDATE_REQ, - KindTradeListingValidateRes = KIND_TRADE_LISTING_VALIDATE_RES, - KindTradeListingOrderReq = KIND_TRADE_LISTING_ORDER_REQ, - KindTradeListingOrderRes = KIND_TRADE_LISTING_ORDER_RES, - KindTradeListingOrderRevisionReq = KIND_TRADE_LISTING_ORDER_REVISION_REQ, - KindTradeListingOrderRevisionRes = KIND_TRADE_LISTING_ORDER_REVISION_RES, - KindTradeListingQuestionReq = KIND_TRADE_LISTING_QUESTION_REQ, - KindTradeListingAnswerRes = KIND_TRADE_LISTING_ANSWER_RES, - KindTradeListingDiscountReq = KIND_TRADE_LISTING_DISCOUNT_REQ, - KindTradeListingDiscountOfferRes = KIND_TRADE_LISTING_DISCOUNT_OFFER_RES, - KindTradeListingDiscountAcceptReq = KIND_TRADE_LISTING_DISCOUNT_ACCEPT_REQ, - KindTradeListingDiscountDeclineReq = KIND_TRADE_LISTING_DISCOUNT_DECLINE_REQ, - KindTradeListingCancelReq = KIND_TRADE_LISTING_CANCEL_REQ, - KindTradeListingFulfillmentUpdateReq = KIND_TRADE_LISTING_FULFILLMENT_UPDATE_REQ, - KindTradeListingReceiptReq = KIND_TRADE_LISTING_RECEIPT_REQ, -} - -#[inline] -pub const fn is_trade_listing_dvm_request_kind(kind: u16) -> bool { - matches!( - kind, - KIND_TRADE_LISTING_VALIDATE_REQ - | KIND_TRADE_LISTING_ORDER_REQ - | KIND_TRADE_LISTING_ORDER_REVISION_REQ - | KIND_TRADE_LISTING_QUESTION_REQ - | KIND_TRADE_LISTING_DISCOUNT_REQ - | KIND_TRADE_LISTING_DISCOUNT_ACCEPT_REQ - | KIND_TRADE_LISTING_DISCOUNT_DECLINE_REQ - | KIND_TRADE_LISTING_CANCEL_REQ - | KIND_TRADE_LISTING_FULFILLMENT_UPDATE_REQ - | KIND_TRADE_LISTING_RECEIPT_REQ - ) -} - -#[inline] -pub const fn is_trade_listing_dvm_result_kind(kind: u16) -> bool { - matches!( - kind, - KIND_TRADE_LISTING_VALIDATE_RES - | KIND_TRADE_LISTING_ORDER_RES - | KIND_TRADE_LISTING_ORDER_REVISION_RES - | KIND_TRADE_LISTING_ANSWER_RES - | KIND_TRADE_LISTING_DISCOUNT_OFFER_RES - ) -} - -#[inline] -pub const fn is_trade_listing_dvm_kind(kind: u16) -> bool { - is_trade_listing_dvm_request_kind(kind) || is_trade_listing_dvm_result_kind(kind) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn classifies_request_and_result_kinds() { - for kind in [ - KIND_TRADE_LISTING_VALIDATE_REQ, - KIND_TRADE_LISTING_ORDER_REQ, - KIND_TRADE_LISTING_ORDER_REVISION_REQ, - KIND_TRADE_LISTING_QUESTION_REQ, - KIND_TRADE_LISTING_DISCOUNT_REQ, - KIND_TRADE_LISTING_DISCOUNT_ACCEPT_REQ, - KIND_TRADE_LISTING_DISCOUNT_DECLINE_REQ, - KIND_TRADE_LISTING_CANCEL_REQ, - KIND_TRADE_LISTING_FULFILLMENT_UPDATE_REQ, - KIND_TRADE_LISTING_RECEIPT_REQ, - ] { - assert!(is_trade_listing_dvm_request_kind(kind)); - assert!(is_trade_listing_dvm_kind(kind)); - assert!(!is_trade_listing_dvm_result_kind(kind)); - } - - for kind in [ - KIND_TRADE_LISTING_VALIDATE_RES, - KIND_TRADE_LISTING_ORDER_RES, - KIND_TRADE_LISTING_ORDER_REVISION_RES, - KIND_TRADE_LISTING_ANSWER_RES, - KIND_TRADE_LISTING_DISCOUNT_OFFER_RES, - ] { - assert!(is_trade_listing_dvm_result_kind(kind)); - assert!(is_trade_listing_dvm_kind(kind)); - assert!(!is_trade_listing_dvm_request_kind(kind)); - } - } - - #[test] - fn rejects_non_trade_dvm_kind() { - assert!(!is_trade_listing_dvm_kind(5000)); - assert!(!is_trade_listing_dvm_request_kind(5000)); - assert!(!is_trade_listing_dvm_result_kind(5000)); - } - - #[test] - fn dvm_kind_array_contains_expected_kind_values() { - assert_eq!(TRADE_LISTING_DVM_KINDS.len(), 15); - assert!(TRADE_LISTING_DVM_KINDS.contains(&KIND_TRADE_LISTING_VALIDATE_REQ)); - assert!(TRADE_LISTING_DVM_KINDS.contains(&KIND_TRADE_LISTING_VALIDATE_RES)); - assert!(TRADE_LISTING_DVM_KINDS.contains(&KIND_TRADE_LISTING_ORDER_REQ)); - assert!(TRADE_LISTING_DVM_KINDS.contains(&KIND_TRADE_LISTING_ORDER_RES)); - assert!(TRADE_LISTING_DVM_KINDS.contains(&KIND_TRADE_LISTING_RECEIPT_REQ)); - } -} diff --git a/crates/trade/src/listing/kinds.rs b/crates/trade/src/listing/kinds.rs @@ -1,32 +1,47 @@ +#![forbid(unsafe_code)] + #[cfg(feature = "ts-rs")] use ts_rs::TS; -pub const KIND_TRADE_LISTING_ORDER_REQ: u16 = 5301; -pub const KIND_TRADE_LISTING_ORDER_RES: u16 = 6301; - -pub const KIND_TRADE_LISTING_ACCEPT_REQ: u16 = 5302; -pub const KIND_TRADE_LISTING_ACCEPT_RES: u16 = 6302; - -pub const KIND_TRADE_LISTING_CONVEYANCE_REQ: u16 = 5303; -pub const KIND_TRADE_LISTING_CONVEYANCE_RES: u16 = 6303; - -pub const KIND_TRADE_LISTING_INVOICE_REQ: u16 = 5304; -pub const KIND_TRADE_LISTING_INVOICE_RES: u16 = 6304; - -pub const KIND_TRADE_LISTING_PAYMENT_REQ: u16 = 5305; -pub const KIND_TRADE_LISTING_PAYMENT_RES: u16 = 6305; - -pub const KIND_TRADE_LISTING_FULFILL_REQ: u16 = 5306; -pub const KIND_TRADE_LISTING_FULFILL_RES: u16 = 6306; - -pub const KIND_TRADE_LISTING_RECEIPT_REQ: u16 = 5307; -pub const KIND_TRADE_LISTING_RECEIPT_RES: u16 = 6307; - -pub const KIND_TRADE_LISTING_CANCEL_REQ: u16 = 5309; -pub const KIND_TRADE_LISTING_CANCEL_RES: u16 = 6309; - -pub const KIND_TRADE_LISTING_REFUND_REQ: u16 = 5310; -pub const KIND_TRADE_LISTING_REFUND_RES: u16 = 6310; +pub const KIND_TRADE_LISTING_VALIDATE_REQ: u16 = 5321; +pub const KIND_TRADE_LISTING_VALIDATE_RES: u16 = 6321; + +pub const KIND_TRADE_LISTING_ORDER_REQ: u16 = 5322; +pub const KIND_TRADE_LISTING_ORDER_RES: u16 = 6322; + +pub const KIND_TRADE_LISTING_ORDER_REVISION_REQ: u16 = 5323; +pub const KIND_TRADE_LISTING_ORDER_REVISION_RES: u16 = 6323; + +pub const KIND_TRADE_LISTING_QUESTION_REQ: u16 = 5324; +pub const KIND_TRADE_LISTING_ANSWER_RES: u16 = 6324; + +pub const KIND_TRADE_LISTING_DISCOUNT_REQ: u16 = 5325; +pub const KIND_TRADE_LISTING_DISCOUNT_OFFER_RES: u16 = 6325; + +pub const KIND_TRADE_LISTING_DISCOUNT_ACCEPT_REQ: u16 = 5326; +pub const KIND_TRADE_LISTING_DISCOUNT_DECLINE_REQ: u16 = 5327; + +pub const KIND_TRADE_LISTING_CANCEL_REQ: u16 = 5328; +pub const KIND_TRADE_LISTING_FULFILLMENT_UPDATE_REQ: u16 = 5329; +pub const KIND_TRADE_LISTING_RECEIPT_REQ: u16 = 5330; + +pub const TRADE_LISTING_KINDS: [u16; 15] = [ + KIND_TRADE_LISTING_VALIDATE_REQ, + KIND_TRADE_LISTING_VALIDATE_RES, + KIND_TRADE_LISTING_ORDER_REQ, + KIND_TRADE_LISTING_ORDER_RES, + KIND_TRADE_LISTING_ORDER_REVISION_REQ, + KIND_TRADE_LISTING_ORDER_REVISION_RES, + KIND_TRADE_LISTING_QUESTION_REQ, + KIND_TRADE_LISTING_ANSWER_RES, + KIND_TRADE_LISTING_DISCOUNT_REQ, + KIND_TRADE_LISTING_DISCOUNT_OFFER_RES, + KIND_TRADE_LISTING_DISCOUNT_ACCEPT_REQ, + KIND_TRADE_LISTING_DISCOUNT_DECLINE_REQ, + KIND_TRADE_LISTING_CANCEL_REQ, + KIND_TRADE_LISTING_FULFILLMENT_UPDATE_REQ, + KIND_TRADE_LISTING_RECEIPT_REQ, +]; #[cfg_attr(feature = "ts-rs", derive(TS))] #[cfg_attr( @@ -41,39 +56,37 @@ pub const KIND_TRADE_LISTING_REFUND_RES: u16 = 6310; #[repr(u16)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum TradeListingKind { + KindTradeListingValidateReq = KIND_TRADE_LISTING_VALIDATE_REQ, + KindTradeListingValidateRes = KIND_TRADE_LISTING_VALIDATE_RES, KindTradeListingOrderReq = KIND_TRADE_LISTING_ORDER_REQ, KindTradeListingOrderRes = KIND_TRADE_LISTING_ORDER_RES, - KindTradeListingAcceptReq = KIND_TRADE_LISTING_ACCEPT_REQ, - KindTradeListingAcceptRes = KIND_TRADE_LISTING_ACCEPT_RES, - KindTradeListingConveyanceReq = KIND_TRADE_LISTING_CONVEYANCE_REQ, - KindTradeListingConveyanceRes = KIND_TRADE_LISTING_CONVEYANCE_RES, - KindTradeListingInvoiceReq = KIND_TRADE_LISTING_INVOICE_REQ, - KindTradeListingInvoiceRes = KIND_TRADE_LISTING_INVOICE_RES, - KindTradeListingPaymentReq = KIND_TRADE_LISTING_PAYMENT_REQ, - KindTradeListingPaymentRes = KIND_TRADE_LISTING_PAYMENT_RES, - KindTradeListingFulfillReq = KIND_TRADE_LISTING_FULFILL_REQ, - KindTradeListingFulfillRes = KIND_TRADE_LISTING_FULFILL_RES, - KindTradeListingReceiptReq = KIND_TRADE_LISTING_RECEIPT_REQ, - KindTradeListingReceiptRes = KIND_TRADE_LISTING_RECEIPT_RES, + KindTradeListingOrderRevisionReq = KIND_TRADE_LISTING_ORDER_REVISION_REQ, + KindTradeListingOrderRevisionRes = KIND_TRADE_LISTING_ORDER_REVISION_RES, + KindTradeListingQuestionReq = KIND_TRADE_LISTING_QUESTION_REQ, + KindTradeListingAnswerRes = KIND_TRADE_LISTING_ANSWER_RES, + KindTradeListingDiscountReq = KIND_TRADE_LISTING_DISCOUNT_REQ, + KindTradeListingDiscountOfferRes = KIND_TRADE_LISTING_DISCOUNT_OFFER_RES, + KindTradeListingDiscountAcceptReq = KIND_TRADE_LISTING_DISCOUNT_ACCEPT_REQ, + KindTradeListingDiscountDeclineReq = KIND_TRADE_LISTING_DISCOUNT_DECLINE_REQ, KindTradeListingCancelReq = KIND_TRADE_LISTING_CANCEL_REQ, - KindTradeListingCancelRes = KIND_TRADE_LISTING_CANCEL_RES, - KindTradeListingRefundReq = KIND_TRADE_LISTING_REFUND_REQ, - KindTradeListingRefundRes = KIND_TRADE_LISTING_REFUND_RES, + KindTradeListingFulfillmentUpdateReq = KIND_TRADE_LISTING_FULFILLMENT_UPDATE_REQ, + KindTradeListingReceiptReq = KIND_TRADE_LISTING_RECEIPT_REQ, } #[inline] pub const fn is_trade_listing_request_kind(kind: u16) -> bool { matches!( kind, - KIND_TRADE_LISTING_ORDER_REQ - | KIND_TRADE_LISTING_ACCEPT_REQ - | KIND_TRADE_LISTING_CONVEYANCE_REQ - | KIND_TRADE_LISTING_INVOICE_REQ - | KIND_TRADE_LISTING_PAYMENT_REQ - | KIND_TRADE_LISTING_FULFILL_REQ - | KIND_TRADE_LISTING_RECEIPT_REQ + KIND_TRADE_LISTING_VALIDATE_REQ + | KIND_TRADE_LISTING_ORDER_REQ + | KIND_TRADE_LISTING_ORDER_REVISION_REQ + | KIND_TRADE_LISTING_QUESTION_REQ + | KIND_TRADE_LISTING_DISCOUNT_REQ + | KIND_TRADE_LISTING_DISCOUNT_ACCEPT_REQ + | KIND_TRADE_LISTING_DISCOUNT_DECLINE_REQ | KIND_TRADE_LISTING_CANCEL_REQ - | KIND_TRADE_LISTING_REFUND_REQ + | KIND_TRADE_LISTING_FULFILLMENT_UPDATE_REQ + | KIND_TRADE_LISTING_RECEIPT_REQ ) } @@ -81,30 +94,27 @@ pub const fn is_trade_listing_request_kind(kind: u16) -> bool { pub const fn is_trade_listing_result_kind(kind: u16) -> bool { matches!( kind, - KIND_TRADE_LISTING_ORDER_RES - | KIND_TRADE_LISTING_ACCEPT_RES - | KIND_TRADE_LISTING_CONVEYANCE_RES - | KIND_TRADE_LISTING_INVOICE_RES - | KIND_TRADE_LISTING_PAYMENT_RES - | KIND_TRADE_LISTING_FULFILL_RES - | KIND_TRADE_LISTING_RECEIPT_RES - | KIND_TRADE_LISTING_CANCEL_RES - | KIND_TRADE_LISTING_REFUND_RES + KIND_TRADE_LISTING_VALIDATE_RES + | KIND_TRADE_LISTING_ORDER_RES + | KIND_TRADE_LISTING_ORDER_REVISION_RES + | KIND_TRADE_LISTING_ANSWER_RES + | KIND_TRADE_LISTING_DISCOUNT_OFFER_RES ) } #[inline] +pub const fn is_trade_listing_kind(kind: u16) -> bool { + is_trade_listing_request_kind(kind) || is_trade_listing_result_kind(kind) +} + +#[inline] pub const fn trade_listing_result_kind_for_request(kind: u16) -> Option<u16> { match kind { + KIND_TRADE_LISTING_VALIDATE_REQ => Some(KIND_TRADE_LISTING_VALIDATE_RES), KIND_TRADE_LISTING_ORDER_REQ => Some(KIND_TRADE_LISTING_ORDER_RES), - KIND_TRADE_LISTING_ACCEPT_REQ => Some(KIND_TRADE_LISTING_ACCEPT_RES), - KIND_TRADE_LISTING_CONVEYANCE_REQ => Some(KIND_TRADE_LISTING_CONVEYANCE_RES), - KIND_TRADE_LISTING_INVOICE_REQ => Some(KIND_TRADE_LISTING_INVOICE_RES), - KIND_TRADE_LISTING_PAYMENT_REQ => Some(KIND_TRADE_LISTING_PAYMENT_RES), - KIND_TRADE_LISTING_FULFILL_REQ => Some(KIND_TRADE_LISTING_FULFILL_RES), - KIND_TRADE_LISTING_RECEIPT_REQ => Some(KIND_TRADE_LISTING_RECEIPT_RES), - KIND_TRADE_LISTING_CANCEL_REQ => Some(KIND_TRADE_LISTING_CANCEL_RES), - KIND_TRADE_LISTING_REFUND_REQ => Some(KIND_TRADE_LISTING_REFUND_RES), + KIND_TRADE_LISTING_ORDER_REVISION_REQ => Some(KIND_TRADE_LISTING_ORDER_REVISION_RES), + KIND_TRADE_LISTING_QUESTION_REQ => Some(KIND_TRADE_LISTING_ANSWER_RES), + KIND_TRADE_LISTING_DISCOUNT_REQ => Some(KIND_TRADE_LISTING_DISCOUNT_OFFER_RES), _ => None, } } @@ -112,15 +122,11 @@ pub const fn trade_listing_result_kind_for_request(kind: u16) -> Option<u16> { #[inline] pub const fn trade_listing_request_kind_for_result(kind: u16) -> Option<u16> { match kind { + KIND_TRADE_LISTING_VALIDATE_RES => Some(KIND_TRADE_LISTING_VALIDATE_REQ), KIND_TRADE_LISTING_ORDER_RES => Some(KIND_TRADE_LISTING_ORDER_REQ), - KIND_TRADE_LISTING_ACCEPT_RES => Some(KIND_TRADE_LISTING_ACCEPT_REQ), - KIND_TRADE_LISTING_CONVEYANCE_RES => Some(KIND_TRADE_LISTING_CONVEYANCE_REQ), - KIND_TRADE_LISTING_INVOICE_RES => Some(KIND_TRADE_LISTING_INVOICE_REQ), - KIND_TRADE_LISTING_PAYMENT_RES => Some(KIND_TRADE_LISTING_PAYMENT_REQ), - KIND_TRADE_LISTING_FULFILL_RES => Some(KIND_TRADE_LISTING_FULFILL_REQ), - KIND_TRADE_LISTING_RECEIPT_RES => Some(KIND_TRADE_LISTING_RECEIPT_REQ), - KIND_TRADE_LISTING_CANCEL_RES => Some(KIND_TRADE_LISTING_CANCEL_REQ), - KIND_TRADE_LISTING_REFUND_RES => Some(KIND_TRADE_LISTING_REFUND_REQ), + KIND_TRADE_LISTING_ORDER_REVISION_RES => Some(KIND_TRADE_LISTING_ORDER_REVISION_REQ), + KIND_TRADE_LISTING_ANSWER_RES => Some(KIND_TRADE_LISTING_QUESTION_REQ), + KIND_TRADE_LISTING_DISCOUNT_OFFER_RES => Some(KIND_TRADE_LISTING_DISCOUNT_REQ), _ => None, } } @@ -130,47 +136,81 @@ mod tests { use super::*; #[test] - fn request_to_result_roundtrip() { + fn classifies_request_and_result_kinds() { + for kind in [ + KIND_TRADE_LISTING_VALIDATE_REQ, + KIND_TRADE_LISTING_ORDER_REQ, + KIND_TRADE_LISTING_ORDER_REVISION_REQ, + KIND_TRADE_LISTING_QUESTION_REQ, + KIND_TRADE_LISTING_DISCOUNT_REQ, + KIND_TRADE_LISTING_DISCOUNT_ACCEPT_REQ, + KIND_TRADE_LISTING_DISCOUNT_DECLINE_REQ, + KIND_TRADE_LISTING_CANCEL_REQ, + KIND_TRADE_LISTING_FULFILLMENT_UPDATE_REQ, + KIND_TRADE_LISTING_RECEIPT_REQ, + ] { + assert!(is_trade_listing_request_kind(kind)); + assert!(is_trade_listing_kind(kind)); + assert!(!is_trade_listing_result_kind(kind)); + } + + for kind in [ + KIND_TRADE_LISTING_VALIDATE_RES, + KIND_TRADE_LISTING_ORDER_RES, + KIND_TRADE_LISTING_ORDER_REVISION_RES, + KIND_TRADE_LISTING_ANSWER_RES, + KIND_TRADE_LISTING_DISCOUNT_OFFER_RES, + ] { + assert!(is_trade_listing_result_kind(kind)); + assert!(is_trade_listing_kind(kind)); + assert!(!is_trade_listing_request_kind(kind)); + } + } + + #[test] + fn request_to_result_roundtrip_is_defined_for_request_response_pairs() { let pairs = [ + (KIND_TRADE_LISTING_VALIDATE_REQ, KIND_TRADE_LISTING_VALIDATE_RES), (KIND_TRADE_LISTING_ORDER_REQ, KIND_TRADE_LISTING_ORDER_RES), - (KIND_TRADE_LISTING_ACCEPT_REQ, KIND_TRADE_LISTING_ACCEPT_RES), - ( - KIND_TRADE_LISTING_CONVEYANCE_REQ, - KIND_TRADE_LISTING_CONVEYANCE_RES, - ), ( - KIND_TRADE_LISTING_INVOICE_REQ, - KIND_TRADE_LISTING_INVOICE_RES, + KIND_TRADE_LISTING_ORDER_REVISION_REQ, + KIND_TRADE_LISTING_ORDER_REVISION_RES, ), + (KIND_TRADE_LISTING_QUESTION_REQ, KIND_TRADE_LISTING_ANSWER_RES), ( - KIND_TRADE_LISTING_PAYMENT_REQ, - KIND_TRADE_LISTING_PAYMENT_RES, + KIND_TRADE_LISTING_DISCOUNT_REQ, + KIND_TRADE_LISTING_DISCOUNT_OFFER_RES, ), - ( - KIND_TRADE_LISTING_FULFILL_REQ, - KIND_TRADE_LISTING_FULFILL_RES, - ), - ( - KIND_TRADE_LISTING_RECEIPT_REQ, - KIND_TRADE_LISTING_RECEIPT_RES, - ), - (KIND_TRADE_LISTING_CANCEL_REQ, KIND_TRADE_LISTING_CANCEL_RES), - (KIND_TRADE_LISTING_REFUND_REQ, KIND_TRADE_LISTING_REFUND_RES), ]; for (req, res) in pairs { assert_eq!(trade_listing_result_kind_for_request(req), Some(res)); assert_eq!(trade_listing_request_kind_for_result(res), Some(req)); - assert!(is_trade_listing_request_kind(req)); - assert!(is_trade_listing_result_kind(res)); } } #[test] - fn request_to_result_rejects_non_trade_kinds() { - assert_eq!(trade_listing_result_kind_for_request(5000), None); - assert_eq!(trade_listing_request_kind_for_result(6000), None); - assert!(!is_trade_listing_request_kind(5000)); - assert!(!is_trade_listing_result_kind(6000)); + fn request_to_result_rejects_non_roundtrip_kinds() { + for kind in [ + KIND_TRADE_LISTING_DISCOUNT_ACCEPT_REQ, + KIND_TRADE_LISTING_DISCOUNT_DECLINE_REQ, + KIND_TRADE_LISTING_CANCEL_REQ, + KIND_TRADE_LISTING_FULFILLMENT_UPDATE_REQ, + KIND_TRADE_LISTING_RECEIPT_REQ, + ] { + assert_eq!(trade_listing_result_kind_for_request(kind), None); + } + assert_eq!(trade_listing_request_kind_for_result(5000), None); + assert!(!is_trade_listing_kind(5000)); + } + + #[test] + fn kind_array_contains_expected_kinds() { + assert_eq!(TRADE_LISTING_KINDS.len(), 15); + assert!(TRADE_LISTING_KINDS.contains(&KIND_TRADE_LISTING_VALIDATE_REQ)); + assert!(TRADE_LISTING_KINDS.contains(&KIND_TRADE_LISTING_VALIDATE_RES)); + assert!(TRADE_LISTING_KINDS.contains(&KIND_TRADE_LISTING_ORDER_REQ)); + assert!(TRADE_LISTING_KINDS.contains(&KIND_TRADE_LISTING_ORDER_RES)); + assert!(TRADE_LISTING_KINDS.contains(&KIND_TRADE_LISTING_RECEIPT_REQ)); } } diff --git a/crates/trade/src/listing/meta.rs b/crates/trade/src/listing/meta.rs @@ -1,452 +0,0 @@ -use core::fmt; -use core::str::FromStr; -#[cfg(feature = "ts-rs")] -use ts_rs::TS; - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr( - feature = "ts-rs", - ts(export, export_to = "types.ts", rename_all = "snake_case", repr(enum = name)) -)] -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub enum TradeListingMarker { - Listing, - Payload, - Previous, - OrderResult, - AcceptResult, - ConveyanceResult, - InvoiceResult, - PaymentResult, - FulfillmentResult, - ReceiptResult, - CancelResult, - RefundResult, - Proof, -} - -impl TradeListingMarker { - #[inline] - pub const fn as_str(self) -> &'static str { - match self { - TradeListingMarker::Listing => "listing", - TradeListingMarker::Payload => "payload", - TradeListingMarker::Previous => "previous", - TradeListingMarker::OrderResult => "order_result", - TradeListingMarker::AcceptResult => "accept_result", - TradeListingMarker::ConveyanceResult => "conveyance_result", - TradeListingMarker::InvoiceResult => "invoice_result", - TradeListingMarker::PaymentResult => "payment_result", - TradeListingMarker::FulfillmentResult => "fulfillment_result", - TradeListingMarker::ReceiptResult => "receipt_result", - TradeListingMarker::CancelResult => "cancel_result", - TradeListingMarker::RefundResult => "refund_result", - TradeListingMarker::Proof => "proof", - } - } -} - -pub const MARKER_LISTING: &str = TradeListingMarker::Listing.as_str(); -pub const MARKER_PAYLOAD: &str = TradeListingMarker::Payload.as_str(); -pub const MARKER_PREVIOUS: &str = TradeListingMarker::Previous.as_str(); - -pub const MARKER_ORDER_RESULT: &str = TradeListingMarker::OrderResult.as_str(); -pub const MARKER_ACCEPT_RESULT: &str = TradeListingMarker::AcceptResult.as_str(); -pub const MARKER_CONVEYANCE_RESULT: &str = TradeListingMarker::ConveyanceResult.as_str(); -pub const MARKER_INVOICE_RESULT: &str = TradeListingMarker::InvoiceResult.as_str(); -pub const MARKER_PAYMENT_RESULT: &str = TradeListingMarker::PaymentResult.as_str(); -pub const MARKER_FULFILLMENT_RESULT: &str = TradeListingMarker::FulfillmentResult.as_str(); -pub const MARKER_RECEIPT_RESULT: &str = TradeListingMarker::ReceiptResult.as_str(); -pub const MARKER_CANCEL_RESULT: &str = TradeListingMarker::CancelResult.as_str(); -pub const MARKER_REFUND_RESULT: &str = TradeListingMarker::RefundResult.as_str(); -pub const MARKER_PROOF: &str = TradeListingMarker::Proof.as_str(); - -const MARKERS_ORDER_REQUEST: [&str; 2] = [MARKER_LISTING, MARKER_PAYLOAD]; -const MARKERS_ACCEPT_REQUEST: [&str; 2] = [MARKER_ORDER_RESULT, MARKER_LISTING]; -const MARKERS_CONVEYANCE_REQUEST: [&str; 2] = [MARKER_ACCEPT_RESULT, MARKER_PAYLOAD]; -const MARKERS_INVOICE_REQUEST: [&str; 1] = [MARKER_ACCEPT_RESULT]; -const MARKERS_PAYMENT_REQUEST: [&str; 2] = [MARKER_INVOICE_RESULT, MARKER_PROOF]; -const MARKERS_FULFILLMENT_REQUEST: [&str; 1] = [MARKER_PAYMENT_RESULT]; -const MARKERS_RECEIPT_REQUEST: [&str; 2] = [MARKER_FULFILLMENT_RESULT, MARKER_PAYLOAD]; -const MARKERS_CANCEL_REQUEST: [&str; 2] = [MARKER_PREVIOUS, MARKER_PAYLOAD]; -const MARKERS_REFUND_REQUEST: [&str; 2] = [MARKER_PAYMENT_RESULT, MARKER_PAYLOAD]; - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[cfg_attr( - feature = "serde", - serde(rename_all = "snake_case", tag = "kind", content = "amount") -)] -pub enum TradeListingStage { - Order, - Accept, - Conveyance, - Invoice, - Payment, - Fulfillment, - Receipt, - Cancel, - Refund, -} - -impl TradeListingStage { - #[inline] - pub const fn as_str(&self) -> &'static str { - match self { - TradeListingStage::Order => "order", - TradeListingStage::Accept => "accept", - TradeListingStage::Conveyance => "conveyance", - TradeListingStage::Invoice => "invoice", - TradeListingStage::Payment => "payment", - TradeListingStage::Fulfillment => "fulfillment", - TradeListingStage::Receipt => "receipt", - TradeListingStage::Cancel => "cancel", - TradeListingStage::Refund => "refund", - } - } - - #[inline] - pub const fn request_kind(&self) -> u16 { - match self { - TradeListingStage::Order => crate::listing::kinds::KIND_TRADE_LISTING_ORDER_REQ, - TradeListingStage::Accept => crate::listing::kinds::KIND_TRADE_LISTING_ACCEPT_REQ, - TradeListingStage::Conveyance => { - crate::listing::kinds::KIND_TRADE_LISTING_CONVEYANCE_REQ - } - TradeListingStage::Invoice => crate::listing::kinds::KIND_TRADE_LISTING_INVOICE_REQ, - TradeListingStage::Payment => crate::listing::kinds::KIND_TRADE_LISTING_PAYMENT_REQ, - TradeListingStage::Fulfillment => crate::listing::kinds::KIND_TRADE_LISTING_FULFILL_REQ, - TradeListingStage::Receipt => crate::listing::kinds::KIND_TRADE_LISTING_RECEIPT_REQ, - TradeListingStage::Cancel => crate::listing::kinds::KIND_TRADE_LISTING_CANCEL_REQ, - TradeListingStage::Refund => crate::listing::kinds::KIND_TRADE_LISTING_REFUND_REQ, - } - } - - #[inline] - pub const fn result_kind(&self) -> u16 { - self.request_kind() + 1000 - } - - #[inline] - pub const fn request_markers(&self) -> &'static [&'static str] { - match self { - TradeListingStage::Order => &MARKERS_ORDER_REQUEST, - TradeListingStage::Accept => &MARKERS_ACCEPT_REQUEST, - TradeListingStage::Conveyance => &MARKERS_CONVEYANCE_REQUEST, - TradeListingStage::Invoice => &MARKERS_INVOICE_REQUEST, - TradeListingStage::Payment => &MARKERS_PAYMENT_REQUEST, - TradeListingStage::Fulfillment => &MARKERS_FULFILLMENT_REQUEST, - TradeListingStage::Receipt => &MARKERS_RECEIPT_REQUEST, - TradeListingStage::Cancel => &MARKERS_CANCEL_REQUEST, - TradeListingStage::Refund => &MARKERS_REFUND_REQUEST, - } - } - - #[inline] - pub const fn result_marker(&self) -> &'static str { - match self { - TradeListingStage::Order => MARKER_ORDER_RESULT, - TradeListingStage::Accept => MARKER_ACCEPT_RESULT, - TradeListingStage::Conveyance => MARKER_CONVEYANCE_RESULT, - TradeListingStage::Invoice => MARKER_INVOICE_RESULT, - TradeListingStage::Payment => MARKER_PAYMENT_RESULT, - TradeListingStage::Fulfillment => MARKER_FULFILLMENT_RESULT, - TradeListingStage::Receipt => MARKER_RECEIPT_RESULT, - TradeListingStage::Cancel => MARKER_CANCEL_RESULT, - TradeListingStage::Refund => MARKER_REFUND_RESULT, - } - } - - #[inline] - pub const fn from_request_kind(kind: u16) -> Option<Self> { - match kind { - crate::listing::kinds::KIND_TRADE_LISTING_ORDER_REQ => Some(TradeListingStage::Order), - crate::listing::kinds::KIND_TRADE_LISTING_ACCEPT_REQ => Some(TradeListingStage::Accept), - crate::listing::kinds::KIND_TRADE_LISTING_CONVEYANCE_REQ => { - Some(TradeListingStage::Conveyance) - } - crate::listing::kinds::KIND_TRADE_LISTING_INVOICE_REQ => { - Some(TradeListingStage::Invoice) - } - crate::listing::kinds::KIND_TRADE_LISTING_PAYMENT_REQ => { - Some(TradeListingStage::Payment) - } - crate::listing::kinds::KIND_TRADE_LISTING_FULFILL_REQ => { - Some(TradeListingStage::Fulfillment) - } - crate::listing::kinds::KIND_TRADE_LISTING_RECEIPT_REQ => { - Some(TradeListingStage::Receipt) - } - crate::listing::kinds::KIND_TRADE_LISTING_CANCEL_REQ => Some(TradeListingStage::Cancel), - crate::listing::kinds::KIND_TRADE_LISTING_REFUND_REQ => Some(TradeListingStage::Refund), - _ => None, - } - } - - #[inline] - pub const fn from_result_kind(kind: u16) -> Option<Self> { - match kind { - crate::listing::kinds::KIND_TRADE_LISTING_ORDER_RES => Some(TradeListingStage::Order), - crate::listing::kinds::KIND_TRADE_LISTING_ACCEPT_RES => Some(TradeListingStage::Accept), - crate::listing::kinds::KIND_TRADE_LISTING_CONVEYANCE_RES => { - Some(TradeListingStage::Conveyance) - } - crate::listing::kinds::KIND_TRADE_LISTING_INVOICE_RES => { - Some(TradeListingStage::Invoice) - } - crate::listing::kinds::KIND_TRADE_LISTING_PAYMENT_RES => { - Some(TradeListingStage::Payment) - } - crate::listing::kinds::KIND_TRADE_LISTING_FULFILL_RES => { - Some(TradeListingStage::Fulfillment) - } - crate::listing::kinds::KIND_TRADE_LISTING_RECEIPT_RES => { - Some(TradeListingStage::Receipt) - } - crate::listing::kinds::KIND_TRADE_LISTING_CANCEL_RES => Some(TradeListingStage::Cancel), - crate::listing::kinds::KIND_TRADE_LISTING_REFUND_RES => Some(TradeListingStage::Refund), - _ => None, - } - } -} - -impl fmt::Display for TradeListingStage { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.as_str()) - } -} - -#[non_exhaustive] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum TradeListingStageParseError { - UnknownStage, -} - -impl fmt::Display for TradeListingStageParseError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - TradeListingStageParseError::UnknownStage => { - write!(f, "unknown trade listing stage") - } - } - } -} - -#[cfg(feature = "std")] -impl std::error::Error for TradeListingStageParseError {} - -impl FromStr for TradeListingStage { - type Err = TradeListingStageParseError; - fn from_str(s: &str) -> Result<Self, Self::Err> { - match s { - "order" => Ok(Self::Order), - "accept" => Ok(Self::Accept), - "conveyance" => Ok(Self::Conveyance), - "invoice" => Ok(Self::Invoice), - "payment" => Ok(Self::Payment), - "fulfillment" => Ok(Self::Fulfillment), - "receipt" => Ok(Self::Receipt), - "cancel" => Ok(Self::Cancel), - "refund" => Ok(Self::Refund), - _ => Err(TradeListingStageParseError::UnknownStage), - } - } -} - -#[cfg(test)] -mod tests { - use super::{ - MARKER_ACCEPT_RESULT, MARKER_CANCEL_RESULT, MARKER_CONVEYANCE_RESULT, - MARKER_FULFILLMENT_RESULT, MARKER_INVOICE_RESULT, MARKER_LISTING, MARKER_ORDER_RESULT, - MARKER_PAYLOAD, MARKER_PAYMENT_RESULT, MARKER_PREVIOUS, MARKER_PROOF, - MARKER_RECEIPT_RESULT, MARKER_REFUND_RESULT, TradeListingStage, - TradeListingStageParseError, - }; - - #[test] - fn stage_roundtrip() { - let cases = [ - (TradeListingStage::Order, "order"), - (TradeListingStage::Accept, "accept"), - (TradeListingStage::Conveyance, "conveyance"), - (TradeListingStage::Invoice, "invoice"), - (TradeListingStage::Payment, "payment"), - (TradeListingStage::Fulfillment, "fulfillment"), - (TradeListingStage::Receipt, "receipt"), - (TradeListingStage::Cancel, "cancel"), - (TradeListingStage::Refund, "refund"), - ]; - - for (stage, name) in cases { - assert_eq!(stage.as_str(), name); - assert_eq!(stage.to_string(), name); - assert_eq!(name.parse::<TradeListingStage>().unwrap(), stage); - } - } - - #[test] - fn stage_parse_rejects_unknown() { - let err = "unknown".parse::<TradeListingStage>().unwrap_err(); - assert_eq!(err, TradeListingStageParseError::UnknownStage); - } - - #[test] - fn stage_kinds_follow_nip_90() { - let cases = [ - TradeListingStage::Order, - TradeListingStage::Accept, - TradeListingStage::Conveyance, - TradeListingStage::Invoice, - TradeListingStage::Payment, - TradeListingStage::Fulfillment, - TradeListingStage::Receipt, - TradeListingStage::Cancel, - TradeListingStage::Refund, - ]; - - for stage in cases { - assert_eq!(stage.result_kind(), stage.request_kind() + 1000); - assert_eq!( - TradeListingStage::from_request_kind(stage.request_kind()), - Some(stage) - ); - assert_eq!( - TradeListingStage::from_result_kind(stage.result_kind()), - Some(stage) - ); - } - } - - #[test] - fn stage_markers_cover_expected_inputs() { - assert_eq!( - TradeListingStage::Order.request_markers(), - &[MARKER_LISTING, MARKER_PAYLOAD] - ); - assert_eq!( - TradeListingStage::Accept.request_markers(), - &[MARKER_ORDER_RESULT, MARKER_LISTING] - ); - assert_eq!( - TradeListingStage::Payment.request_markers(), - &[MARKER_INVOICE_RESULT, MARKER_PROOF] - ); - assert_eq!( - TradeListingStage::Fulfillment.request_markers(), - &[MARKER_PAYMENT_RESULT] - ); - assert_eq!( - TradeListingStage::Receipt.request_markers(), - &[MARKER_FULFILLMENT_RESULT, MARKER_PAYLOAD] - ); - assert_eq!( - TradeListingStage::Refund.request_markers(), - &[MARKER_PAYMENT_RESULT, MARKER_PAYLOAD] - ); - assert_eq!( - TradeListingStage::Order.result_marker(), - MARKER_ORDER_RESULT - ); - assert_eq!( - TradeListingStage::Conveyance.result_marker(), - MARKER_CONVEYANCE_RESULT - ); - assert_eq!( - TradeListingStage::Receipt.result_marker(), - MARKER_RECEIPT_RESULT - ); - } - - #[test] - fn marker_as_str_covers_all_variants() { - let cases = [ - (super::TradeListingMarker::Listing, "listing"), - (super::TradeListingMarker::Payload, "payload"), - (super::TradeListingMarker::Previous, "previous"), - (super::TradeListingMarker::OrderResult, "order_result"), - (super::TradeListingMarker::AcceptResult, "accept_result"), - ( - super::TradeListingMarker::ConveyanceResult, - "conveyance_result", - ), - (super::TradeListingMarker::InvoiceResult, "invoice_result"), - (super::TradeListingMarker::PaymentResult, "payment_result"), - ( - super::TradeListingMarker::FulfillmentResult, - "fulfillment_result", - ), - (super::TradeListingMarker::ReceiptResult, "receipt_result"), - (super::TradeListingMarker::CancelResult, "cancel_result"), - (super::TradeListingMarker::RefundResult, "refund_result"), - (super::TradeListingMarker::Proof, "proof"), - ]; - for (marker, name) in cases { - assert_eq!(marker.as_str(), name); - } - } - - #[test] - fn marker_constants_match_marker_strings() { - assert_eq!(MARKER_LISTING, super::TradeListingMarker::Listing.as_str()); - assert_eq!(MARKER_PAYLOAD, super::TradeListingMarker::Payload.as_str()); - assert_eq!( - MARKER_PREVIOUS, - super::TradeListingMarker::Previous.as_str() - ); - assert_eq!( - MARKER_ACCEPT_RESULT, - super::TradeListingMarker::AcceptResult.as_str() - ); - assert_eq!( - MARKER_CANCEL_RESULT, - super::TradeListingMarker::CancelResult.as_str() - ); - assert_eq!( - MARKER_REFUND_RESULT, - super::TradeListingMarker::RefundResult.as_str() - ); - } - - #[test] - fn stage_marker_tables_cover_all_variants_and_unknown_kinds() { - let request_cases = [ - ( - TradeListingStage::Conveyance, - vec![MARKER_ACCEPT_RESULT, MARKER_PAYLOAD], - ), - (TradeListingStage::Invoice, vec![MARKER_ACCEPT_RESULT]), - ( - TradeListingStage::Cancel, - vec![MARKER_PREVIOUS, MARKER_PAYLOAD], - ), - ]; - for (stage, expected) in request_cases { - assert_eq!(stage.request_markers(), expected.as_slice()); - } - - let result_cases = [ - (TradeListingStage::Accept, MARKER_ACCEPT_RESULT), - (TradeListingStage::Invoice, MARKER_INVOICE_RESULT), - (TradeListingStage::Payment, MARKER_PAYMENT_RESULT), - (TradeListingStage::Fulfillment, MARKER_FULFILLMENT_RESULT), - (TradeListingStage::Cancel, MARKER_CANCEL_RESULT), - (TradeListingStage::Refund, MARKER_REFUND_RESULT), - ]; - for (stage, expected) in result_cases { - assert_eq!(stage.result_marker(), expected); - } - - assert_eq!(TradeListingStage::from_request_kind(0), None); - assert_eq!(TradeListingStage::from_result_kind(0), None); - } - - #[test] - fn stage_parse_error_display_is_stable() { - assert_eq!( - TradeListingStageParseError::UnknownStage.to_string(), - "unknown trade listing stage" - ); - } -} diff --git a/crates/trade/src/listing/mod.rs b/crates/trade/src/listing/mod.rs @@ -1,20 +1,8 @@ pub mod codec; pub mod dvm; -pub mod dvm_kinds; pub mod kinds; -pub mod meta; pub mod model; pub mod order; pub mod price_ext; pub mod tags; pub mod validation; - -pub mod stage { - pub mod accept; - pub mod conveyance; - pub mod fulfillment; - pub mod invoice; - pub mod order; - pub mod payment; - pub mod receipt; -} diff --git a/crates/trade/src/listing/stage/accept.rs b/crates/trade/src/listing/stage/accept.rs @@ -1,23 +0,0 @@ -#[cfg(not(feature = "std"))] -use alloc::string::String; -#[cfg(feature = "ts-rs")] -use ts_rs::TS; - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug)] -pub struct TradeListingAcceptRequest { - pub order_result_event_id: String, - pub listing_event_id: String, -} - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug)] -pub struct TradeListingAcceptResult { - pub listing_event_id: String, - pub order_result_event_id: String, - pub accepted_by: String, -} diff --git a/crates/trade/src/listing/stage/conveyance.rs b/crates/trade/src/listing/stage/conveyance.rs @@ -1,48 +0,0 @@ -#[cfg(not(feature = "std"))] -use alloc::string::String; -#[cfg(feature = "ts-rs")] -use ts_rs::TS; - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug)] -#[cfg_attr( - feature = "serde", - serde(rename_all = "snake_case", tag = "kind", content = "amount") -)] -pub enum TradeListingConveyanceMethod { - SellerDelivery { - window: Option<String>, - notes: Option<String>, - }, - BuyerPickup { - location_hint: Option<String>, - by_when: Option<String>, - }, - ThirdParty { - provider: String, - ref_id: Option<String>, - notes: Option<String>, - }, -} - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug)] -pub struct TradeListingConveyanceRequest { - pub accept_result_event_id: String, - pub method: TradeListingConveyanceMethod, -} - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug)] -pub struct TradeListingConveyanceResult { - pub verified: bool, - pub method: TradeListingConveyanceMethod, - #[cfg_attr(feature = "ts-rs", ts(optional, type = "string | null"))] - pub message: Option<String>, -} diff --git a/crates/trade/src/listing/stage/fulfillment.rs b/crates/trade/src/listing/stage/fulfillment.rs @@ -1,42 +0,0 @@ -#[cfg(not(feature = "std"))] -use alloc::string::String; -#[cfg(feature = "ts-rs")] -use ts_rs::TS; - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug)] -pub struct TradeListingFulfillmentRequest { - pub payment_result_event_id: String, -} - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug)] -#[cfg_attr( - feature = "serde", - serde(rename_all = "snake_case", tag = "kind", content = "amount") -)] -pub enum TradeListingFulfillmentState { - Preparing, - Shipped, - ReadyForPickup, - Delivered, - Canceled, -} - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug)] -pub struct TradeListingFulfillmentResult { - pub state: TradeListingFulfillmentState, - #[cfg_attr(feature = "ts-rs", ts(optional, type = "string | null"))] - pub tracking: Option<String>, - #[cfg_attr(feature = "ts-rs", ts(optional, type = "string | null"))] - pub eta: Option<String>, - #[cfg_attr(feature = "ts-rs", ts(optional, type = "string | null"))] - pub notes: Option<String>, -} diff --git a/crates/trade/src/listing/stage/invoice.rs b/crates/trade/src/listing/stage/invoice.rs @@ -1,26 +0,0 @@ -#[cfg(not(feature = "std"))] -use alloc::string::String; -#[cfg(feature = "ts-rs")] -use ts_rs::TS; - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug)] -pub struct TradeListingInvoiceRequest { - pub accept_result_event_id: String, -} - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug)] -pub struct TradeListingInvoiceResult { - pub total_sat: u32, - #[cfg_attr(feature = "ts-rs", ts(optional, type = "string | null"))] - pub bolt11: Option<String>, - #[cfg_attr(feature = "ts-rs", ts(optional, type = "string | null"))] - pub note: Option<String>, - #[cfg_attr(feature = "ts-rs", ts(optional, type = "number | null"))] - pub expires_at: Option<u32>, -} diff --git a/crates/trade/src/listing/stage/order.rs b/crates/trade/src/listing/stage/order.rs @@ -1,41 +0,0 @@ -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; -use radroots_core::{RadrootsCoreDiscount, RadrootsCoreQuantityPrice}; -#[cfg(feature = "ts-rs")] -use ts_rs::TS; - -use crate::listing::model::{RadrootsTradeListingSubtotal, RadrootsTradeListingTotal}; - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug)] -pub struct TradeListingOrderRequestPayload { - pub bin_id: String, - pub bin_count: u32, -} - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug)] -pub struct TradeListingOrderRequest { - #[cfg_attr(feature = "ts-rs", ts(type = "RadrootsNostrEventPtr"))] - pub event: radroots_events::RadrootsNostrEventPtr, - pub payload: TradeListingOrderRequestPayload, -} - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug)] -pub struct TradeListingOrderResult { - pub bin_id: String, - pub bin_count: u32, - #[cfg_attr(feature = "ts-rs", ts(type = "RadrootsCoreQuantityPrice"))] - pub price: RadrootsCoreQuantityPrice, - #[cfg_attr(feature = "ts-rs", ts(type = "RadrootsCoreDiscount[]"))] - pub discounts: Vec<RadrootsCoreDiscount>, - pub subtotal: RadrootsTradeListingSubtotal, - pub total: RadrootsTradeListingTotal, -} diff --git a/crates/trade/src/listing/stage/payment.rs b/crates/trade/src/listing/stage/payment.rs @@ -1,38 +0,0 @@ -#[cfg(not(feature = "std"))] -use alloc::string::String; -#[cfg(feature = "ts-rs")] -use ts_rs::TS; - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug)] -#[cfg_attr( - feature = "serde", - serde(rename_all = "snake_case", tag = "kind", content = "amount") -)] -pub enum TradeListingPaymentProof { - ZapEvent { id: String }, - Preimage { hex: String }, - Txid { id: String }, - ExternalRef { provider: String, ref_id: String }, -} - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug)] -pub struct TradeListingPaymentProofRequest { - pub invoice_result_event_id: String, - pub proof: TradeListingPaymentProof, -} - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug)] -pub struct TradeListingPaymentResult { - pub verified: bool, - #[cfg_attr(feature = "ts-rs", ts(optional, type = "string | null"))] - pub message: Option<String>, -} diff --git a/crates/trade/src/listing/stage/receipt.rs b/crates/trade/src/listing/stage/receipt.rs @@ -1,23 +0,0 @@ -#[cfg(not(feature = "std"))] -use alloc::string::String; -#[cfg(feature = "ts-rs")] -use ts_rs::TS; - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug)] -pub struct TradeListingReceiptRequest { - pub fulfillment_result_event_id: String, - #[cfg_attr(feature = "ts-rs", ts(optional, type = "string | null"))] - pub note: Option<String>, -} - -#[cfg_attr(feature = "ts-rs", derive(TS))] -#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug)] -pub struct TradeListingReceiptResult { - pub acknowledged: bool, - pub at: u32, -}