use serde::{Deserialize, Serialize};
pub const PAYMENT_VERSION: &str = "1.0";
pub const DEFAULT_SATOSHIS: u64 = 100;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BSVPayment {
pub derivation_prefix: String,
pub derivation_suffix: String,
pub transaction: serde_json::Value,
}
#[derive(Clone, Debug)]
pub struct PaymentInfo {
pub satoshis_paid: u64,
pub accepted: Option<bool>,
pub tx: Option<serde_json::Value>,
}
pub type CalculateRequestPrice = Box<
dyn Fn(
&actix_web::dev::ServiceRequest,
) -> futures_util::future::BoxFuture<
'static,
Result<u64, Box<dyn std::error::Error + Send + Sync>>,
> + Send
+ Sync,
>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bsv_payment_deserialize_camel_case() {
let json = r#"{"derivationPrefix":"abc","derivationSuffix":"def","transaction":"tx"}"#;
let payment: BSVPayment = serde_json::from_str(json).unwrap();
assert_eq!(payment.derivation_prefix, "abc");
assert_eq!(payment.derivation_suffix, "def");
assert_eq!(payment.transaction, serde_json::json!("tx"));
}
#[test]
fn test_bsv_payment_serialize_camel_case() {
let payment = BSVPayment {
derivation_prefix: "abc".to_string(),
derivation_suffix: "def".to_string(),
transaction: serde_json::json!("tx"),
};
let json = serde_json::to_string(&payment).unwrap();
assert!(json.contains("derivationPrefix"));
assert!(json.contains("derivationSuffix"));
assert!(json.contains("transaction"));
assert!(!json.contains("derivation_prefix"));
assert!(!json.contains("derivation_suffix"));
}
#[test]
fn test_bsv_payment_round_trip() {
let original = BSVPayment {
derivation_prefix: "prefix123".to_string(),
derivation_suffix: "suffix456".to_string(),
transaction: serde_json::json!({"hex": "deadbeef"}),
};
let json = serde_json::to_string(&original).unwrap();
let deserialized: BSVPayment = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.derivation_prefix, original.derivation_prefix);
assert_eq!(deserialized.derivation_suffix, original.derivation_suffix);
assert_eq!(deserialized.transaction, original.transaction);
}
#[test]
fn test_payment_version_constant() {
assert_eq!(PAYMENT_VERSION, "1.0");
}
#[test]
fn test_default_satoshis_constant() {
assert_eq!(DEFAULT_SATOSHIS, 100);
}
#[test]
fn test_payment_info_struct() {
let info = PaymentInfo {
satoshis_paid: 200,
accepted: Some(true),
tx: Some(serde_json::json!({"txid": "abc"})),
};
assert_eq!(info.satoshis_paid, 200);
assert_eq!(info.accepted, Some(true));
assert!(info.tx.is_some());
}
#[test]
fn test_payment_info_clone() {
let info = PaymentInfo {
satoshis_paid: 100,
accepted: None,
tx: None,
};
let cloned = info.clone();
assert_eq!(cloned.satoshis_paid, 100);
assert_eq!(cloned.accepted, None);
assert!(cloned.tx.is_none());
}
}