use naia_derive::MessageInternal;
use crate::{
messages::channels::{
receivers::fragment_receiver::FragmentReceiver,
senders::message_fragmenter::MessageFragmenter,
},
FakeEntityConverter, MessageContainer, MessageKinds, Protocol,
};
#[derive(MessageInternal)]
pub struct StringMessage {
pub inner: String,
}
impl StringMessage {
pub fn new(inner: &str) -> Self {
Self {
inner: inner.to_string(),
}
}
}
fn setup() -> (
MessageKinds,
FakeEntityConverter,
MessageFragmenter,
FragmentReceiver,
) {
let mut protocol = Protocol::builder();
protocol.add_message::<StringMessage>();
let converter = FakeEntityConverter;
let fragmenter = MessageFragmenter::new();
let receiver = FragmentReceiver::new();
(protocol.message_kinds, converter, fragmenter, receiver)
}
#[test]
fn convert_single_fragment() {
let (message_kinds, converter, mut fragmenter, mut receiver) = setup();
let initial_message = StringMessage::new("hello");
let outgoing_message = initial_message.clone();
let container = MessageContainer::from_write(Box::new(outgoing_message), &FakeEntityConverter);
let fragments = fragmenter.fragment_message(&message_kinds, &converter, container);
let fragment_count = fragments.len();
let mut incoming_message_container_opt = None;
for fragment in fragments {
if let Some((_, reassembled_message)) =
receiver.receive(&message_kinds, &converter, fragment)
{
incoming_message_container_opt = Some(reassembled_message);
break;
}
}
let Some(incoming_message_container) = incoming_message_container_opt else {
panic!("Did not receive reassembled message!");
};
let Ok(incoming_message) = incoming_message_container
.to_boxed_any()
.downcast::<StringMessage>()
else {
panic!("cannot cast message container into proper message!");
};
assert_eq!(fragment_count, 1);
assert_eq!(initial_message.inner, incoming_message.inner);
}
#[test]
fn convert_multiple_fragments() {
let (message_kinds, converter, mut fragmenter, mut receiver) = setup();
let initial_message = StringMessage::new("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec sed justo a mi ultricies ultrices. \
Sed porta, odio eu rhoncus venenatis, massa elit posuere nisl, sit amet venenatis mi mi at erat. \
Vivamus non ullamcorper augue, non pharetra augue. Fusce erat ante, iaculis id maximus eu, faucibus consequat nisl. \
Integer consequat consequat bibendum. Cras nisl est, lacinia nec ipsum vitae, pulvinar elementum orci. \
Nullam in mauris vel nulla convallis laoreet vitae in turpis. Proin dignissim mattis ante, a lacinia neque sodales id. \
Donec ac sollicitudin nunc. Nam luctus nulla ut nisi tristique, quis scelerisque neque elementum. Etiam a quam turpis. \
Vestibulum ultricies dui et porttitor blandit. Etiam turpis quam, pretium ac convallis a, blandit sit amet ipsum. \
Sed ut pharetra arcu. Pellentesque id magna sapien. Suspendisse potenti. \
Donec ut purus venenatis, mollis est ut, sollicitudin egestas.");
let outgoing_message = initial_message.clone();
let container = MessageContainer::from_write(Box::new(outgoing_message), &FakeEntityConverter);
let fragments = fragmenter.fragment_message(&message_kinds, &converter, container);
let fragment_count = fragments.len();
let mut incoming_message_container_opt = None;
for i in 0..fragments.len() {
let j = match i {
0 => 1,
1 => 0,
x => x,
};
let fragment = &fragments[j];
if let Some((_, reassembled_message)) =
receiver.receive(&message_kinds, &converter, fragment.clone())
{
incoming_message_container_opt = Some(reassembled_message);
break;
}
}
let Some(incoming_message_container) = incoming_message_container_opt else {
panic!("Did not receive reassembled message!");
};
let Ok(incoming_message) = incoming_message_container
.to_boxed_any()
.downcast::<StringMessage>()
else {
panic!("cannot cast message container into proper message!");
};
assert_eq!(fragment_count, 3);
assert_eq!(initial_message.inner, incoming_message.inner);
}