1use crate::errors::Result;
6use crate::event::{Event, Signer};
7use crate::grammar::Grammar;
8use crate::store::InMemoryStore;
9use crate::types::{ActorId, ConversationId, DomainScope, EventId, Weight};
10
11pub struct MarketGrammar<'a>(Grammar<'a>);
13
14impl<'a> MarketGrammar<'a> {
15 pub fn new(store: &'a mut InMemoryStore) -> Self {
16 Self(Grammar::new(store))
17 }
18
19 pub fn list(&mut self, source: ActorId, offering: &str, causes: Vec<EventId>, conv_id: ConversationId, signer: &dyn Signer) -> Result<Event> {
23 self.0.emit(source, &format!("list: {offering}"), conv_id, causes, signer)
24 }
25
26 pub fn bid(&mut self, source: ActorId, offer: &str, listing: EventId, conv_id: ConversationId, signer: &dyn Signer) -> Result<Event> {
28 self.0.respond(source, &format!("bid: {offer}"), listing, conv_id, signer)
29 }
30
31 pub fn inquire(&mut self, source: ActorId, question: &str, listing: EventId, conv_id: ConversationId, signer: &dyn Signer) -> Result<Event> {
33 self.0.respond(source, &format!("inquire: {question}"), listing, conv_id, signer)
34 }
35
36 pub fn negotiate(&mut self, source: ActorId, counterparty: ActorId, scope: Option<&DomainScope>, cause: EventId, conv_id: ConversationId, signer: &dyn Signer) -> Result<Event> {
38 self.0.channel(source, counterparty, scope, cause, conv_id, signer)
39 }
40
41 pub fn accept(&mut self, buyer: ActorId, seller: ActorId, terms: &str, scope: &DomainScope, cause: EventId, conv_id: ConversationId, signer: &dyn Signer) -> Result<Event> {
43 self.0.consent(buyer, seller, &format!("accept: {terms}"), scope, cause, conv_id, signer)
44 }
45
46 pub fn decline(&mut self, source: ActorId, reason: &str, causes: Vec<EventId>, conv_id: ConversationId, signer: &dyn Signer) -> Result<Event> {
48 self.0.emit(source, &format!("decline: {reason}"), conv_id, causes, signer)
49 }
50
51 pub fn invoice(&mut self, source: ActorId, description: &str, causes: Vec<EventId>, conv_id: ConversationId, signer: &dyn Signer) -> Result<Event> {
53 self.0.emit(source, &format!("invoice: {description}"), conv_id, causes, signer)
54 }
55
56 pub fn pay(&mut self, source: ActorId, description: &str, causes: Vec<EventId>, conv_id: ConversationId, signer: &dyn Signer) -> Result<Event> {
58 self.0.emit(source, &format!("pay: {description}"), conv_id, causes, signer)
59 }
60
61 pub fn deliver(&mut self, source: ActorId, description: &str, causes: Vec<EventId>, conv_id: ConversationId, signer: &dyn Signer) -> Result<Event> {
63 self.0.emit(source, &format!("deliver: {description}"), conv_id, causes, signer)
64 }
65
66 pub fn confirm(&mut self, source: ActorId, confirmation: &str, causes: Vec<EventId>, conv_id: ConversationId, signer: &dyn Signer) -> Result<Event> {
68 self.0.emit(source, &format!("confirm: {confirmation}"), conv_id, causes, signer)
69 }
70
71 pub fn rate(&mut self, source: ActorId, target: EventId, target_actor: ActorId, weight: Weight, scope: Option<&DomainScope>, conv_id: ConversationId, signer: &dyn Signer) -> Result<Event> {
73 self.0.endorse(source, target, target_actor, weight, scope, conv_id, signer)
74 }
75
76 pub fn dispute(&mut self, source: ActorId, complaint: &str, target: EventId, conv_id: ConversationId, signer: &dyn Signer) -> Result<Event> {
78 let (_, flag) = self.0.challenge(source, &format!("dispute: {complaint}"), target, conv_id, signer)?;
79 Ok(flag)
80 }
81
82 pub fn escrow(&mut self, source: ActorId, escrow_actor: ActorId, scope: &DomainScope, weight: Weight, cause: EventId, conv_id: ConversationId, signer: &dyn Signer) -> Result<Event> {
84 self.0.delegate(source, escrow_actor, scope, weight, cause, conv_id, signer)
85 }
86
87 pub fn release(&mut self, party_a: ActorId, party_b: ActorId, terms: &str, scope: &DomainScope, cause: EventId, conv_id: ConversationId, signer: &dyn Signer) -> Result<Event> {
89 self.0.consent(party_a, party_b, &format!("release: {terms}"), scope, cause, conv_id, signer)
90 }
91
92 pub fn auction(
96 &mut self, seller: ActorId, offering: &str,
97 bidders: &[ActorId], bids: &[&str], winner_idx: usize,
98 scope: &DomainScope, causes: Vec<EventId>,
99 conv_id: ConversationId, signer: &dyn Signer,
100 ) -> Result<AuctionResult> {
101 if bidders.len() != bids.len() {
102 return Err(crate::errors::EventGraphError::GrammarViolation { detail: "auction: bidders and bids must have equal length".to_string() });
103 }
104 if winner_idx >= bidders.len() {
105 return Err(crate::errors::EventGraphError::GrammarViolation { detail: "auction: winner_idx out of range".to_string() });
106 }
107 let listing = self.list(seller.clone(), offering, causes, conv_id.clone(), signer)?;
108 let mut bid_events = Vec::new();
109 for (i, bidder) in bidders.iter().enumerate() {
110 let b = self.bid(bidder.clone(), bids[i], listing.id.clone(), conv_id.clone(), signer)?;
111 bid_events.push(b);
112 }
113 let acceptance = self.accept(bidders[winner_idx].clone(), seller, &format!("auction won: {}", bids[winner_idx]), scope, bid_events[winner_idx].id.clone(), conv_id, signer)?;
114 Ok(AuctionResult { listing, bids: bid_events, acceptance })
115 }
116
117 pub fn milestone(
119 &mut self, buyer: ActorId, seller: ActorId,
120 terms: &str, milestones: &[&str], payments: &[&str],
121 scope: &DomainScope, cause: EventId,
122 conv_id: ConversationId, signer: &dyn Signer,
123 ) -> Result<MilestoneResult> {
124 if milestones.len() != payments.len() {
125 return Err(crate::errors::EventGraphError::GrammarViolation { detail: "milestone: milestones and payments must have equal length".to_string() });
126 }
127 let acceptance = self.accept(buyer.clone(), seller.clone(), terms, scope, cause, conv_id.clone(), signer)?;
128 let mut deliveries = Vec::new();
129 let mut payment_events = Vec::new();
130 let mut prev = acceptance.id.clone();
131 for i in 0..milestones.len() {
132 let d = self.deliver(seller.clone(), milestones[i], vec![prev], conv_id.clone(), signer)?;
133 let p = self.pay(buyer.clone(), payments[i], vec![d.id.clone()], conv_id.clone(), signer)?;
134 prev = p.id.clone();
135 deliveries.push(d);
136 payment_events.push(p);
137 }
138 Ok(MilestoneResult { acceptance, deliveries, payments: payment_events })
139 }
140
141 pub fn barter(
143 &mut self, party_a: ActorId, party_b: ActorId,
144 offer_a: &str, offer_b: &str, scope: &DomainScope,
145 causes: Vec<EventId>, conv_id: ConversationId, signer: &dyn Signer,
146 ) -> Result<BarterResult> {
147 let listing = self.list(party_a.clone(), offer_a, causes, conv_id.clone(), signer)?;
148 let counter = self.bid(party_b.clone(), offer_b, listing.id.clone(), conv_id.clone(), signer)?;
149 let acceptance = self.accept(party_a, party_b, &format!("barter: {offer_a} for {offer_b}"), scope, counter.id.clone(), conv_id, signer)?;
150 Ok(BarterResult { listing, counter_offer: counter, acceptance })
151 }
152
153 pub fn subscription(
155 &mut self, subscriber: ActorId, provider: ActorId,
156 terms: &str, periods: &[&str], deliveries: &[&str],
157 scope: &DomainScope, cause: EventId,
158 conv_id: ConversationId, signer: &dyn Signer,
159 ) -> Result<SubscriptionResult> {
160 if periods.len() != deliveries.len() {
161 return Err(crate::errors::EventGraphError::GrammarViolation { detail: "subscription: periods and deliveries must have equal length".to_string() });
162 }
163 let acceptance = self.accept(subscriber.clone(), provider.clone(), terms, scope, cause, conv_id.clone(), signer)?;
164 let mut payment_events = Vec::new();
165 let mut delivery_events = Vec::new();
166 let mut prev = acceptance.id.clone();
167 for i in 0..periods.len() {
168 let p = self.pay(subscriber.clone(), periods[i], vec![prev], conv_id.clone(), signer)?;
169 let d = self.deliver(provider.clone(), deliveries[i], vec![p.id.clone()], conv_id.clone(), signer)?;
170 prev = d.id.clone();
171 payment_events.push(p);
172 delivery_events.push(d);
173 }
174 Ok(SubscriptionResult { acceptance, payments: payment_events, deliveries: delivery_events })
175 }
176
177 pub fn refund(
179 &mut self, buyer: ActorId, seller: ActorId,
180 complaint: &str, resolution: &str, refund_amount: &str,
181 target: EventId, conv_id: ConversationId, signer: &dyn Signer,
182 ) -> Result<RefundResult> {
183 let dispute_ev = self.dispute(buyer.clone(), complaint, target, conv_id.clone(), signer)?;
184 let resolution_ev = self.0.emit(seller.clone(), &format!("resolution: {resolution}"), conv_id.clone(), vec![dispute_ev.id.clone()], signer)?;
185 let reversal = self.pay(seller, &format!("refund: {refund_amount}"), vec![resolution_ev.id.clone()], conv_id, signer)?;
186 Ok(RefundResult { dispute: dispute_ev, resolution: resolution_ev, reversal })
187 }
188
189 pub fn reputation_transfer(
191 &mut self, raters: &[ActorId], targets: &[EventId], target_actor: ActorId,
192 weights: &[Weight], scope: Option<&DomainScope>,
193 conv_id: ConversationId, signer: &dyn Signer,
194 ) -> Result<ReputationTransferResult> {
195 if raters.len() != targets.len() || raters.len() != weights.len() {
196 return Err(crate::errors::EventGraphError::GrammarViolation { detail: "reputation-transfer: raters, targets, and weights must have equal length".to_string() });
197 }
198 let mut ratings = Vec::new();
199 for (i, rater) in raters.iter().enumerate() {
200 let r = self.rate(rater.clone(), targets[i].clone(), target_actor.clone(), weights[i], scope, conv_id.clone(), signer)?;
201 ratings.push(r);
202 }
203 Ok(ReputationTransferResult { ratings })
204 }
205
206 pub fn arbitration(
208 &mut self, plaintiff: ActorId, defendant: ActorId, arbiter: ActorId,
209 complaint: &str, scope: &DomainScope, weight: Weight,
210 target: EventId, conv_id: ConversationId, signer: &dyn Signer,
211 ) -> Result<ArbitrationResult> {
212 let dispute_ev = self.dispute(plaintiff.clone(), complaint, target, conv_id.clone(), signer)?;
213 let escrow_ev = self.escrow(defendant, arbiter.clone(), scope, weight, dispute_ev.id.clone(), conv_id.clone(), signer)?;
214 let release_ev = self.release(arbiter, plaintiff, "arbitration resolved", scope, escrow_ev.id.clone(), conv_id, signer)?;
215 Ok(ArbitrationResult { dispute: dispute_ev, escrow: escrow_ev, release: release_ev })
216 }
217}
218
219pub struct AuctionResult { pub listing: Event, pub bids: Vec<Event>, pub acceptance: Event }
220pub struct MilestoneResult { pub acceptance: Event, pub deliveries: Vec<Event>, pub payments: Vec<Event> }
221pub struct BarterResult { pub listing: Event, pub counter_offer: Event, pub acceptance: Event }
222pub struct SubscriptionResult { pub acceptance: Event, pub payments: Vec<Event>, pub deliveries: Vec<Event> }
223pub struct RefundResult { pub dispute: Event, pub resolution: Event, pub reversal: Event }
224pub struct ReputationTransferResult { pub ratings: Vec<Event> }
225pub struct ArbitrationResult { pub dispute: Event, pub escrow: Event, pub release: Event }