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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//! # server_mocker_instruction
//!
//! Instructions for the mocked server.

/// Represents socket message sent and received by the server mocker.
pub type BinaryMessage = Vec<u8>;

/// Type of network instruction executed by the server mocker.
#[derive(Debug, Clone, PartialEq)]
pub enum ServerMockerInstruction {
    /// Send given message to the client
    SendMessage(BinaryMessage),
    /// Wait for a message to be received. The message could be recovered with [TcpServerMocker::pop_received_message()](../tcp_server_mocker/struct.TcpServerMocker.html#method.pop_received_message)
    ReceiveMessage,
    /// Stop the exchange with the client, close the connection
    StopExchange,
}

/// Represents a list of network instructions to be executed by the server mocker
///
/// The list is executed in order, one instruction at a time.
///
/// The list is executed in a loop, until the [StopExchange](enum.ServerMockerInstruction.html#variant.StopExchange) instruction is received.
#[derive(Debug, Clone, PartialEq)]
pub struct ServerMockerInstructionsList {
    pub(crate) instructions: Vec<ServerMockerInstruction>,
}

/// Creates a new ServerMockerInstructionsList with the given instructions
///
/// # Example
/// ```
/// use socket_server_mocker::server_mocker_instruction::{ServerMockerInstruction, ServerMockerInstructionsList};
/// let mut instructions_list = ServerMockerInstructionsList::new_with_instructions([
///     ServerMockerInstruction::ReceiveMessage,
///     ServerMockerInstruction::SendMessage("hello from server".as_bytes().to_vec()),
/// ].as_slice()).with_added_receive_message();
/// instructions_list.add_stop_exchange();
/// ```
impl ServerMockerInstructionsList {
    /// Creates a new ServerMockerInstructionsList without instruction
    pub fn new() -> ServerMockerInstructionsList {
        ServerMockerInstructionsList {
            instructions: Vec::new(),
        }
    }

    /// Creates a new ServerMockerInstructionsList with the given instructions
    ///
    /// Takes a slice of ServerMockerInstruction and clone it into the new ServerMockerInstructionsList
    pub fn new_with_instructions(
        instructions: &[ServerMockerInstruction],
    ) -> ServerMockerInstructionsList {
        ServerMockerInstructionsList {
            instructions: instructions.to_vec(),
        }
    }

    /// Add instruction for sending a message to the client
    ///
    /// Takes self as a mutable reference
    ///
    /// Message is given as a [BinaryMessage](type.BinaryMessage.html)
    pub fn add_send_message(&mut self, message: BinaryMessage) {
        self.instructions
            .push(ServerMockerInstruction::SendMessage(message));
    }

    /// Add instruction for sending a message to the client
    ///
    /// Takes ownership of self and returns a new ServerMockerInstructionsList
    ///
    /// Message is given as a [BinaryMessage](type.BinaryMessage.html)
    pub fn with_added_send_message(mut self, message: BinaryMessage) -> Self {
        self.add_send_message(message);
        self
    }

    /// Add instruction for waiting for a message to be received from the client
    ///
    /// Takes self as a mutable reference
    ///
    /// The message could be recovered with [TcpServerMocker::pop_received_message()](../tcp_server_mocker/struct.TcpServerMocker.html#method.pop_received_message)
    pub fn add_receive_message(&mut self) {
        self.instructions
            .push(ServerMockerInstruction::ReceiveMessage);
    }

    /// Add instruction for waiting for a message to be received from the client
    ///
    /// Takes ownership of self and returns a new ServerMockerInstructionsList
    ///
    /// The message could be recovered with [TcpServerMocker::pop_received_message()](../tcp_server_mocker/struct.TcpServerMocker.html#method.pop_received_message)
    pub fn with_added_receive_message(mut self) -> Self {
        self.add_receive_message();
        self
    }

    /// Add instruction for stopping the exchange with the client, closing the connection.
    ///
    /// Once the connection is closed, the client will receive an error when trying to send a message.
    ///
    /// Takes self as a mutable reference
    pub fn add_stop_exchange(&mut self) {
        self.instructions
            .push(ServerMockerInstruction::StopExchange);
    }

    /// Add instruction for stopping the exchange with the client, closing the connection.
    ///
    /// Once the connection is closed, the client will receive an error when trying to send a message.
    ///
    /// Takes ownership of self and returns a new ServerMockerInstructionsList
    pub fn with_added_stop_exchange(mut self) -> Self {
        self.add_stop_exchange();
        self
    }
}