sdk_status.rs (6837B)
1 use radroots_events::ids::RadrootsEventId; 2 use radroots_sdk::{ 3 OrderStatusEligibility, OrderStatusEvidenceSummary, OrderStatusKind, OrderStatusNextActionKind, 4 OrderStatusReceipt, SdkOrderStatusIssue, 5 }; 6 7 use crate::view::runtime::{ 8 OrderIssueView, OrderStatusEligibilityView, OrderStatusEvidenceSummaryView, 9 OrderStatusLifecycleCancellationView, OrderStatusLifecycleView, OrderStatusSdkReceiptView, 10 OrderStatusView, 11 }; 12 13 use super::{ORDER_ACTOR_CONTEXT_SDK_LOCAL, ORDER_STATUS_SDK_SOURCE}; 14 15 pub(super) fn sdk_order_status_view(receipt: OrderStatusReceipt) -> OrderStatusView { 16 let state = sdk_order_status_state(receipt.status).to_owned(); 17 let reducer_issues = receipt 18 .issues 19 .iter() 20 .map(sdk_order_status_issue_view) 21 .collect::<Vec<_>>(); 22 let reason = sdk_order_status_reason(receipt.status, receipt.order_id.as_str()); 23 let lifecycle = sdk_order_status_lifecycle_view(&receipt, reducer_issues.as_slice()); 24 let sdk_receipt = Some(sdk_order_status_receipt_view(&receipt)); 25 26 OrderStatusView { 27 state, 28 source: ORDER_STATUS_SDK_SOURCE.to_owned(), 29 order_id: receipt.order_id.to_string(), 30 actor_context_source: ORDER_ACTOR_CONTEXT_SDK_LOCAL.to_owned(), 31 request_event_id: sdk_event_id_string(receipt.request_event_id.as_ref()), 32 decision_event_id: sdk_event_id_string(receipt.decision_event_id.as_ref()), 33 agreement_event_id: sdk_order_status_agreement_event_id(&receipt), 34 listing_event_id: None, 35 listing_addr: receipt.listing_addr.as_ref().map(ToString::to_string), 36 buyer_pubkey: receipt.buyer_pubkey.as_ref().map(ToString::to_string), 37 seller_pubkey: receipt.seller_pubkey.as_ref().map(ToString::to_string), 38 economics: receipt.economics.clone(), 39 last_event_id: sdk_event_id_string(receipt.last_event_id.as_ref()), 40 revision: None, 41 inventory: None, 42 lifecycle: Some(lifecycle), 43 sdk_receipt, 44 reducer_issues, 45 target_relays: Vec::new(), 46 connected_relays: Vec::new(), 47 failed_relays: Vec::new(), 48 fetched_count: 0, 49 decoded_count: receipt.event_count, 50 skipped_count: 0, 51 reason, 52 actions: Vec::new(), 53 } 54 } 55 56 fn sdk_order_status_receipt_view(receipt: &OrderStatusReceipt) -> OrderStatusSdkReceiptView { 57 OrderStatusSdkReceiptView { 58 next_action: sdk_status_next_action(receipt.next_action).to_owned(), 59 evidence: sdk_status_evidence_view(&receipt.evidence), 60 eligibility: sdk_status_eligibility_view(&receipt.eligibility), 61 } 62 } 63 64 fn sdk_status_evidence_view( 65 evidence: &OrderStatusEvidenceSummary, 66 ) -> OrderStatusEvidenceSummaryView { 67 OrderStatusEvidenceSummaryView { 68 event_count: evidence.event_count, 69 limit_applied: evidence.limit_applied, 70 has_request: evidence.has_request, 71 has_decision: evidence.has_decision, 72 has_agreement: evidence.has_agreement, 73 has_pending_revision: evidence.has_pending_revision, 74 has_cancellation: evidence.has_cancellation, 75 has_issues: evidence.has_issues, 76 } 77 } 78 79 fn sdk_status_eligibility_view(eligibility: &OrderStatusEligibility) -> OrderStatusEligibilityView { 80 OrderStatusEligibilityView { 81 can_decide: eligibility.can_decide, 82 can_propose_revision: eligibility.can_propose_revision, 83 can_decide_revision: eligibility.can_decide_revision, 84 can_cancel: eligibility.can_cancel, 85 } 86 } 87 88 fn sdk_status_next_action(kind: OrderStatusNextActionKind) -> &'static str { 89 match kind { 90 OrderStatusNextActionKind::NoLocalOrder => "no_local_order", 91 OrderStatusNextActionKind::InspectEvidenceIssues => "inspect_evidence_issues", 92 OrderStatusNextActionKind::AwaitSellerDecision => "await_seller_decision", 93 OrderStatusNextActionKind::DecideRevision => "decide_revision", 94 OrderStatusNextActionKind::Terminal => "terminal", 95 _ => "unknown", 96 } 97 } 98 99 fn sdk_order_status_state(status: OrderStatusKind) -> &'static str { 100 match status { 101 OrderStatusKind::Missing => "missing", 102 OrderStatusKind::Requested => "requested", 103 OrderStatusKind::Accepted => "accepted", 104 OrderStatusKind::Declined => "declined", 105 OrderStatusKind::Cancelled => "cancelled", 106 OrderStatusKind::Invalid => "invalid", 107 _ => "unknown", 108 } 109 } 110 111 fn sdk_order_status_reason(status: OrderStatusKind, order_id: &str) -> Option<String> { 112 match status { 113 OrderStatusKind::Missing => Some(format!("no local SDK order events matched `{order_id}`")), 114 OrderStatusKind::Invalid => Some(format!( 115 "local SDK order events for `{order_id}` failed reducer validation" 116 )), 117 _ => None, 118 } 119 } 120 121 fn sdk_order_status_agreement_event_id(receipt: &OrderStatusReceipt) -> Option<String> { 122 sdk_event_id_string(receipt.agreement_event_id.as_ref()) 123 } 124 125 fn sdk_order_status_lifecycle_view( 126 receipt: &OrderStatusReceipt, 127 issues: &[OrderIssueView], 128 ) -> OrderStatusLifecycleView { 129 let cancellation = receipt.cancellation_event_id.as_ref().map(|event_id| { 130 OrderStatusLifecycleCancellationView { 131 event_id: event_id.to_string(), 132 root_event_id: sdk_event_id_string(receipt.request_event_id.as_ref()), 133 prev_event_id: sdk_event_id_string(receipt.decision_event_id.as_ref()), 134 reason: None, 135 } 136 }); 137 OrderStatusLifecycleView { 138 phase: sdk_order_status_lifecycle_phase(receipt).to_owned(), 139 terminal: receipt.lifecycle_terminal, 140 event_id: sdk_event_id_string(receipt.last_event_id.as_ref()), 141 root_event_id: sdk_event_id_string(receipt.request_event_id.as_ref()), 142 prev_event_id: None, 143 cancellation, 144 issues: issues.to_vec(), 145 } 146 } 147 148 fn sdk_order_status_lifecycle_phase(receipt: &OrderStatusReceipt) -> &'static str { 149 match receipt.status { 150 OrderStatusKind::Missing => "missing", 151 OrderStatusKind::Requested => "requested", 152 OrderStatusKind::Accepted => "accepted", 153 OrderStatusKind::Declined => "declined", 154 OrderStatusKind::Cancelled => "cancelled", 155 OrderStatusKind::Invalid => "invalid", 156 _ => "unknown", 157 } 158 } 159 160 fn sdk_order_status_issue_view(issue: &SdkOrderStatusIssue) -> OrderIssueView { 161 let code = issue.code(); 162 OrderIssueView { 163 code: code.clone(), 164 field: "sdk_order_status".to_owned(), 165 message: format!("SDK order status reported `{code}`"), 166 event_ids: issue 167 .event_ids 168 .iter() 169 .map(RadrootsEventId::to_string) 170 .collect(), 171 } 172 } 173 174 fn sdk_event_id_string(event_id: Option<&RadrootsEventId>) -> Option<String> { 175 event_id.map(RadrootsEventId::to_string) 176 }