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
64
65
66
67
68
use serde::{Deserialize, Serialize};
use sqlx::types::chrono::Utc;
use sqlx::FromRow;
use sqlx::Type;
use sqlx_crud::SqlxCrud;
use std::fmt;
use std::str::FromStr;
use uuid::Uuid;

/// Each status that a dispute can have
#[derive(Debug, Deserialize, Serialize, Type, Clone, PartialEq, Eq)]
pub enum Status {
    /// Dispute initiated and waiting to be taken by a solver
    Pending,
    /// Taken by a solver
    InProgress,
    /// Canceled by admin/solver and refunded to seller
    SellerRefunded,
    /// Settled seller's invoice by admin/solver and started to pay sats to buyer
    Settled,
    /// Released by the seller
    Released,
}

impl fmt::Display for Status {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{self:?}")
    }
}

impl FromStr for Status {
    type Err = ();

    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
        match s {
            "Pending" => std::result::Result::Ok(Self::Pending),
            "InProgress" => std::result::Result::Ok(Self::InProgress),
            "SellerRefunded" => std::result::Result::Ok(Self::SellerRefunded),
            "Settled" => std::result::Result::Ok(Self::Settled),
            "Released" => std::result::Result::Ok(Self::Released),
            _ => Err(()),
        }
    }
}

/// Database representation of a dispute
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq, FromRow, SqlxCrud)]
pub struct Dispute {
    pub id: Uuid,
    pub order_id: Uuid,
    pub status: Status,
    pub solver_pubkey: Option<String>,
    pub created_at: i64,
    pub taken_at: i64,
}

impl Dispute {
    pub fn new(order_id: Uuid) -> Self {
        Self {
            id: Uuid::new_v4(),
            order_id,
            status: Status::Pending,
            solver_pubkey: None,
            created_at: Utc::now().timestamp(),
            taken_at: 0,
        }
    }
}