payrail_core/
idempotency.rs1use crate::PaymentError;
2
3#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5pub struct IdempotencyKey(String);
6
7impl IdempotencyKey {
8 pub fn new(value: impl AsRef<str>) -> Result<Self, PaymentError> {
14 let value = value.as_ref().trim();
15 if value.is_empty() || value.len() > 255 {
16 return Err(PaymentError::InvalidIdempotencyKey(value.to_owned()));
17 }
18
19 Ok(Self(value.to_owned()))
20 }
21
22 #[inline]
24 #[must_use]
25 pub fn as_str(&self) -> &str {
26 &self.0
27 }
28}
29
30impl AsRef<str> for IdempotencyKey {
31 #[inline]
32 fn as_ref(&self) -> &str {
33 self.as_str()
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40
41 #[test]
42 fn new_accepts_key() {
43 let key = IdempotencyKey::new("ORDER-123:create").expect("key should be valid");
44
45 assert_eq!(key.as_str(), "ORDER-123:create");
46 }
47
48 #[test]
49 fn new_rejects_empty_key() {
50 assert!(matches!(
51 IdempotencyKey::new(""),
52 Err(PaymentError::InvalidIdempotencyKey(_))
53 ));
54 }
55}