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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
use crate::comm::types::message::{MessageState, MessageType};
use pyo3::prelude::*;

use super::IngestedTokens;

// Define the base interface for event callbacks
pub trait ChannelInterface {
	/// Receive tokens in python from rust
	fn receive_tokens_in_python(&mut self) -> Option<IngestedTokens>;
	/// Send tokens in rust from python
	fn send_tokens_in_rust(&mut self, tokens: IngestedTokens);
	/// Receive a message in python from rust
	fn receive_in_python(&mut self) -> Option<MessageState>;
	/// Send a message in rust from python
	fn send_in_rust(&mut self, message_type: MessageType, message_data: MessageState);
}

// Define a basic event handler struct
#[derive(Clone, Debug)]
#[pyclass]
pub struct ChannelHandler {
	pub token_receiver: Option<crossbeam_channel::Receiver<IngestedTokens>>,
	pub token_sender: Option<crossbeam_channel::Sender<IngestedTokens>>,
	pub py_message_receiver: Option<crossbeam_channel::Receiver<(MessageType, MessageState)>>,
	pub message_sender: Option<crossbeam_channel::Sender<(MessageType, MessageState)>>,
}

impl ChannelHandler {
	// Constructor for EventHandler
	pub fn new(
		token_sender: Option<crossbeam_channel::Sender<IngestedTokens>>,
		token_receiver: Option<crossbeam_channel::Receiver<IngestedTokens>>,
		py_message_receiver: Option<crossbeam_channel::Receiver<(MessageType, MessageState)>>,
		message_sender: Option<crossbeam_channel::Sender<(MessageType, MessageState)>>,
	) -> Self {
		ChannelHandler { py_message_receiver, token_sender, token_receiver, message_sender }
	}
}

// Define a Python-compatible message
#[derive(Clone, Debug)]
#[pyclass]
pub struct PyMessageInterface {
	// Internal channel handler instance
	channel_handler: ChannelHandler,
}

// Implement Python methods for PyEventCallbackInterface
#[pymethods]
impl PyMessageInterface {
	// Python constructor for PyMessageInterface
	#[new]
	pub fn new(channel: ChannelHandler) -> Self {
		PyMessageInterface { channel_handler: channel }
	}

	// Receive tokens in python from rust
	pub fn receive_tokens_in_python(&mut self) -> Option<IngestedTokens> {
		// Delegate the event handling to the internal event handler
		self.channel_handler.receive_tokens_in_python()
	}

	// Send tokens in rust from python
	pub fn send_tokens_in_rust(&mut self, tokens: IngestedTokens) {
		// Delegate the event handling to the internal event handler
		self.channel_handler.send_tokens_in_rust(tokens)
	}

	// Python method to handle messages
	pub fn receive_in_python(&mut self) -> Option<MessageState> {
		// Delegate the event handling to the internal event handler
		self.channel_handler.receive_in_python()
	}
	// Python method to handle messages
	pub fn send_in_rust(&mut self, message_type: MessageType, message_data: MessageState) {
		// Delegate the event handling to the internal event handler
		self.channel_handler.send_in_rust(message_type, message_data)
	}
}

// Implement the ChannelInterface for the ChannelHandler
impl ChannelInterface for ChannelHandler {
	fn receive_tokens_in_python(&mut self) -> Option<IngestedTokens> {
		if self.token_receiver.is_some() {
			let token = self.token_receiver.as_ref();
			match token {
				Some(token) => {
					let token = token.try_recv();
					match token {
						Ok(token) => Some(token),
						Err(_) => None,
					}
				},
				None => None,
			}
		} else {
			None
		}
	}

	fn send_tokens_in_rust(&mut self, tokens: IngestedTokens) {
		if self.token_sender.is_some() {
			let token = self.token_sender.as_ref();
			match token {
				Some(token) => {
					let token = token.send(tokens);
					match token {
						Ok(_) => (),
						Err(_) => (),
					}
				},
				None => (),
			}
		} else {
			()
		}
	}

	// Implementation of the handle_event method for EventHandler
	fn receive_in_python(&mut self) -> Option<MessageState> {
		if self.py_message_receiver.is_some() {
			let message = self.py_message_receiver.as_ref();
			match message {
				Some(message) => {
					let message = message.try_recv();
					match message {
						Ok(message) => Some(message.1),
						Err(_) => None,
					}
				},
				None => None,
			}
		} else {
			None
		}
	}

	// Implementation of the handle_event method for EventHandler
	fn send_in_rust(&mut self, message_type: MessageType, message_data: MessageState) {
		if self.message_sender.is_some() {
			let message = self.message_sender.as_ref();
			match message {
				Some(message) => {
					let message = message.send((message_type, message_data));
					match message {
						Ok(_) => (),
						Err(_) => (),
					}
				},
				None => (),
			}
		} else {
			()
		}
	}
}