I thought I'd try swap out slack-morphism's slack blocks for slack-block-rs but I hit a bit of a snag. I'll start with the code producing the issue, though most details aren't significant:
#[tokio::test]
#[serial]
async fn should_initiate_socket_mode_connection() {
let websocket_server = async move {
let mut stream = start_websocket_server().await;
stream
.send(Message::Text(String::from(FAKE_HELLO_MESSAGE)))
.await
.unwrap();
stream
.send(Message::Text(String::from(FAKE_SLACK_TEXT_MESSAGE)))
.await
.unwrap();
};
let handle = tokio::spawn(websocket_server);
let builder = TestClientBuilder::new("should_initiate_socket_mode_connection");
let client = builder.new_client();
let mut listener = client.connect_to_socket_mode().await.unwrap();
let result = listener.next().await;
assert_eq!(result.unwrap(), SocketMessage::Hello {});
let result = listener.next().await;
assert_eq!(
result.unwrap(),
SocketMessage::Event {
envelope_id: String::from("fake-enve-lope-i-d"),
payload: Payload {
event: Event {
id: "1686321337.206879".to_string(),
event_type: "message".to_string(),
text: Some("test".to_string()),
user: Some("F4K3USER1D".to_string()),
blocks: vec![Block::Section(blox! {
<section_block>
<text kind=plain>"test"</text>
</section_block>
})],
channel: Some("F4K3CH4NN3L1D".to_string()),
channel_type: Some("im".to_string()),
}
}
}
);
handle.abort();
}
It's a simple test with a bunch of setup. The important part is that we're getting a result from a socket (listener.next()) and comparing it to an expected result, part of which is built using blox!. That results in this compile error:
error[E0597]: `*listener` does not live long enough
--> client/tests/web_sockets.rs:47:18
|
47 | let result = listener.next().await;
| ^^^^^^^^^^^^^^^ borrowed value does not live long enough
...
58 | blocks: vec![Block::Section(blox! {
| _____________________________-
59 | | <section_block>
60 | | <text kind=plain>"test"</text>
61 | | </section_block>
62 | | })],
| |_______________________- cast requires that `*listener` is borrowed for `'static`
...
70 | }
| - `*listener` dropped here while still borrowed
It's a weird compile error. It is definitely caused by blox!. If I replace the vector with vec![Block::Divider], it works. Using a builder also works.
If I've understood what is happening here correctly, I think it is that: SectionBlock relies on lifetimes and mox is automatically providing a 'static lifetime. Which makes sense, because we're providing this data statically. But result is not using static lifetimes. And I'll often be receiving data from sockets that will only last a short time, certainly not until the end of the program.
Have I understood this right? Is there no way to use blox! without static lifetimes?
And if I may ask as an aside, why use so many generic lifetime parameters anyway? That's a genuine question, not intended as a criticism, I'm just trying to learn more about Rust patterns. It seems like if the models didn't use str and Cow they wouldn't need explicit lifetimes. So what was the intention behind using Cow and str rather than Box or Arc and String? Was it to reduce allocations?
I thought I'd try swap out
slack-morphism's slack blocks forslack-block-rsbut I hit a bit of a snag. I'll start with the code producing the issue, though most details aren't significant:It's a simple test with a bunch of setup. The important part is that we're getting a result from a socket (
listener.next()) and comparing it to an expected result, part of which is built usingblox!. That results in this compile error:It's a weird compile error. It is definitely caused by
blox!. If I replace the vector withvec![Block::Divider], it works. Using a builder also works.If I've understood what is happening here correctly, I think it is that:
SectionBlockrelies on lifetimes andmoxis automatically providing a'staticlifetime. Which makes sense, because we're providing this data statically. Butresultis not using static lifetimes. And I'll often be receiving data from sockets that will only last a short time, certainly not until the end of the program.Have I understood this right? Is there no way to use
blox!without static lifetimes?And if I may ask as an aside, why use so many generic lifetime parameters anyway? That's a genuine question, not intended as a criticism, I'm just trying to learn more about Rust patterns. It seems like if the models didn't use
strandCowthey wouldn't need explicit lifetimes. So what was the intention behind usingCowandstrrather thanBoxorArcandString? Was it to reduce allocations?