1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//! Reject message type for the Transaction Authorization Protocol.
//!
//! This module defines the Reject message type, which is used
//! for rejecting transactions in the TAP protocol.
use serde::{Deserialize, Serialize};
use crate::error::{Error, Result};
use crate::TapMessage;
/// Reject message body (TAIP-4).
#[derive(Debug, Clone, Serialize, Deserialize, TapMessage)]
#[tap(message_type = "https://tap.rsvp/schema/1.0#Reject")]
pub struct Reject {
/// ID of the transaction being rejected.
#[tap(thread_id)]
pub transaction_id: String,
/// Reason for rejection.
#[serde(skip_serializing_if = "Option::is_none", default)]
pub reason: Option<String>,
}
impl Reject {
/// Create a new Reject message
pub fn new(transaction_id: &str, reason: &str) -> Self {
Self {
transaction_id: transaction_id.to_string(),
reason: Some(reason.to_string()),
}
}
/// Create a minimal Reject message (for testing/special cases)
pub fn minimal(transaction_id: &str) -> Self {
Self {
transaction_id: transaction_id.to_string(),
reason: None,
}
}
}
impl Reject {
/// Custom validation for Reject messages
pub fn validate_reject(&self) -> Result<()> {
if self.transaction_id.is_empty() {
return Err(Error::Validation(
"Transaction ID is required in Reject".to_string(),
));
}
// Note: reason is now optional to support minimal test cases
// In production use, a reason should typically be provided
if let Some(ref reason) = self.reason {
if reason.is_empty() {
return Err(Error::Validation(
"Reason cannot be empty when provided".to_string(),
));
}
}
Ok(())
}
}