paystack/models/
terminal_models.rs

1//! Terminal
2//! ==========
3//! This file contains the models and options for the Terminal endpoint of the Paystack
4
5use derive_builder::Builder;
6use serde::{Deserialize, Serialize};
7use std::fmt;
8
9use crate::Domain;
10
11/// The request body to send an event from your application to the Paystack Terminal
12#[derive(Debug, Clone, Builder, Serialize, Deserialize)]
13pub struct EventRequest {
14    #[serde(rename = "type")]
15    pub event_type: EventType,
16    pub action: TerminalAction,
17    pub data: EventRequestData,
18}
19
20/// The paramters needed to perform the specified action.
21///
22/// For the invoice type, you need to pass the invoice id and offline reference: {id: invoice_id, reference: offline_reference}.
23///
24/// For the transaction type, you can pass the transaction id: {id: transaction_id}, reference field can be `None`
25#[derive(Debug, Serialize, Deserialize, Clone, Builder)]
26pub struct EventRequestData {
27    pub id: String,
28    #[builder(setter(strip_option), default)]
29    pub reference: Option<String>,
30}
31
32/// The type of event to push.
33/// Paystack currently support `invoice` and `transaction`
34#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
35pub enum EventType {
36    Invoice,
37    Transaction,
38}
39
40/// The action the Terminal needs to perform.
41///
42/// - For the `Invoice` type, the action can either be `Process` or `View`.
43///
44/// - For the `Transaction` type, the action can either be `Process` or `Print`.
45#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
46pub enum TerminalAction {
47    Process,
48    View,
49    Print,
50}
51
52impl fmt::Display for TerminalAction {
53    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
54        let action = match self {
55            TerminalAction::Process => "process",
56            TerminalAction::Print => "print",
57            TerminalAction::View => "view",
58        };
59        write!(f, "{action}")
60    }
61}
62
63impl fmt::Display for EventType {
64    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
65        let event = match self {
66            EventType::Invoice => "invoice",
67            EventType::Transaction => "transaction",
68        };
69        write!(f, "{event}")
70    }
71}
72
73/// Update request for terminal
74#[derive(Debug, Serialize, Deserialize, Builder, Default)]
75pub struct UpdateTerminalRequest {
76    /// Name of the terminal
77    #[builder(setter(strip_option), default)]
78    pub address: Option<String>,
79    /// The address of the terminal
80    #[builder(setter(strip_option), default)]
81    pub name: Option<String>,
82}
83
84/// Response data for the send event route in the terminal endpoint.
85#[derive(Serialize, Deserialize, Debug, Clone, Default)]
86pub struct SendEventResponseData {
87    pub id: String,
88}
89
90/// Response data for the fetch event status route in the terminal endpoint.
91#[derive(Serialize, Deserialize, Debug, Clone, Default)]
92pub struct FetchEventStatusResponseData {
93    pub delivered: bool,
94}
95
96/// Response data for fetch terminal status route in the terminal endpoint.
97#[derive(Serialize, Deserialize, Debug, Clone, Default)]
98pub struct FetchTerminalStatusResponseData {
99    pub online: bool,
100    pub available: bool,
101}
102
103/// Response data for terminal
104#[derive(Serialize, Deserialize, Debug, Clone, Default)]
105pub struct TerminalData {
106    pub id: u64,
107    pub serial_number: String,
108    pub device_make: Option<String>,
109    pub terminal_id: String,
110    pub integration: u64,
111    pub domain: Domain,
112    pub name: String,
113    pub address: Option<String>,
114    pub status: String,
115}
116
117#[cfg(test)]
118mod tests {
119    use super::*;
120
121    #[test]
122    fn create_event_request() {
123        let even_request_data = EventRequestDataBuilder::default()
124            .id("some-id".to_string())
125            .reference("some-ref".to_string())
126            .build()
127            .expect("failed to build event request data");
128
129        let event_request = EventRequestBuilder::default()
130            .event_type(EventType::Invoice)
131            .action(TerminalAction::Process)
132            .data(even_request_data)
133            .build()
134            .expect("failed to build event request");
135
136        assert_eq!(&event_request.event_type, &EventType::Invoice);
137        assert_eq!(&event_request.action, &TerminalAction::Process);
138        assert_eq!(&event_request.data.id, "some-id");
139        assert_eq!(&event_request.data.reference, &Some("some-ref".to_string()))
140    }
141
142    #[test]
143    fn create_update_terminal_request() {
144        let update_request = UpdateTerminalRequestBuilder::default()
145            .address("some-address".to_string())
146            .name("some-name".to_string())
147            .build()
148            .expect("failed to build update terminal request");
149
150        assert_eq!(update_request.address, Some("some-address".to_string()));
151        assert_eq!(update_request.name, Some("some-name".to_string()));
152    }
153}