Skip to content

Commit 10b2984

Browse files
authored
add rama support to datastar rust sdk (#847)
* add rama support to datastar rust sdk Closes #845 * bump rama alpha version
1 parent 6b2d488 commit 10b2984

File tree

11 files changed

+334
-16
lines changed

11 files changed

+334
-16
lines changed

build/run.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ func writeOutConsts(version string) error {
152152
"examples/ruby/hello-world/hello-world.html": helloWorldExample,
153153
"examples/rust/axum/hello-world/hello-world.html": helloWorldExample,
154154
"examples/rust/rocket/hello-world/hello-world.html": helloWorldExample,
155+
"examples/rust/rama/hello-world/hello-world.html": helloWorldExample,
155156
}
156157

157158
for path, tmplFn := range templates {

examples/rust/axum/hello-world/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
[package]
2-
edition = "2021"
2+
edition = "2024"
33
name = "hello_world"
44
version = "0.1.0"
5+
rust-version = "1.85.0"
56

67
[dependencies]
78
async-stream = "0.3.6"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
target
2+
Cargo.lock
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[package]
2+
edition = "2024"
3+
name = "hello_world"
4+
version = "0.1.0"
5+
rust-version = "1.85.0"
6+
7+
[dependencies]
8+
async-stream = "0.3.6"
9+
rama = { version = "0.2.0-alpha.11", features = ["http-full"] }
10+
datastar = { path = "../../../../sdk/rust", features = ["rama"] }
11+
futures = "0.3.31"
12+
serde = { version = "1.0.217", features = ["derive"] }
13+
tokio = { version = "1.43.0", features = ["full"] }
14+
tokio-stream = "0.1.17"
15+
tracing = "0.1.41"
16+
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!-- This is auto-generated by Datastar. DO NOT EDIT. -->
2+
3+
<!DOCTYPE html>
4+
<html lang="en">
5+
<head>
6+
<title>Datastar SDK Demo</title>
7+
<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
8+
<script type="module" src="https://cdn.jsdelivr.net/gh/starfederation/[email protected]/bundles/datastar.js"></script>
9+
</head>
10+
<body class="bg-white dark:bg-gray-900 text-lg max-w-xl mx-auto my-16">
11+
<div data-signals-delay="400" class="bg-white dark:bg-gray-800 text-gray-500 dark:text-gray-400 rounded-lg px-6 py-8 ring shadow-xl ring-gray-900/5 space-y-2">
12+
<div class="flex justify-between items-center">
13+
<h1 class="text-gray-900 dark:text-white text-3xl font-semibold">
14+
Datastar SDK Demo
15+
</h1>
16+
<img src="https://data-star.dev/static/images/rocket.png" alt="Rocket" width="64" height="64"/>
17+
</div>
18+
<p class="mt-2">
19+
SSE events will be streamed from the backend to the frontend.
20+
</p>
21+
<div class="space-x-2">
22+
<label for="delay">
23+
Delay in milliseconds
24+
</label>
25+
<input data-bind-delay id="delay" type="number" step="100" min="0" class="w-36 rounded-md border border-gray-300 px-3 py-2 placeholder-gray-400 shadow-sm focus:border-sky-500 focus:outline focus:outline-sky-500 dark:disabled:border-gray-700 dark:disabled:bg-gray-800/20" />
26+
</div>
27+
<button data-on-click="@get(&#39;/hello-world&#39;)" class="rounded-md bg-sky-500 px-5 py-2.5 leading-5 font-semibold text-white hover:bg-sky-700 hover:text-gray-100 cursor-pointer">
28+
Start
29+
</button>
30+
</div>
31+
<div class="my-16 text-8xl font-bold text-transparent" style="background: linear-gradient(to right in oklch, red, orange, yellow, green, blue, blue, violet); background-clip: text">
32+
<div id="message">Hello, world!</div>
33+
</div>
34+
</body>
35+
</html>
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use {
2+
async_stream::stream,
3+
core::time::Duration,
4+
datastar::{
5+
Sse,
6+
prelude::{MergeFragments, ReadSignals},
7+
},
8+
rama::{
9+
error::BoxError,
10+
http::{IntoResponse, response::Html, server::HttpServer, service::web::Router},
11+
rt::Executor,
12+
},
13+
serde::Deserialize,
14+
tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt},
15+
};
16+
17+
#[tokio::main]
18+
async fn main() -> Result<(), BoxError> {
19+
tracing_subscriber::registry()
20+
.with(
21+
tracing_subscriber::EnvFilter::try_from_default_env()
22+
.unwrap_or_else(|_| format!("{}=debug", env!("CARGO_CRATE_NAME")).into()),
23+
)
24+
.with(tracing_subscriber::fmt::layer())
25+
.init();
26+
27+
let app = Router::new()
28+
.get("/", index)
29+
.get("/hello-world", hello_world);
30+
31+
tracing::debug!("listening on 127.0.0.1:3000");
32+
HttpServer::auto(Executor::default())
33+
.listen("127.0.0.1:3000", app)
34+
.await?;
35+
36+
Ok(())
37+
}
38+
39+
async fn index() -> Html<&'static str> {
40+
Html(include_str!("../hello-world.html"))
41+
}
42+
43+
const MESSAGE: &str = "Hello, world!";
44+
45+
#[derive(Deserialize)]
46+
pub struct Signals {
47+
pub delay: u64,
48+
}
49+
50+
async fn hello_world(ReadSignals(signals): ReadSignals<Signals>) -> impl IntoResponse {
51+
Sse(stream! {
52+
for i in 0..MESSAGE.len() {
53+
yield MergeFragments::new(format!("<div id='message'>{}</div>", &MESSAGE[0..i + 1])).into();
54+
tokio::time::sleep(Duration::from_millis(signals.delay)).await;
55+
}
56+
})
57+
}

examples/rust/rocket/hello-world/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
[package]
2-
edition = "2021"
2+
edition = "2024"
33
name = "hello_world"
44
version = "0.1.0"
5+
rust-version = "1.85.0"
56

67
[dependencies]
78
datastar = { path = "../../../../sdk/rust", features = ["rocket"] }

sdk/rust/Cargo.toml

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,51 @@
11
[package]
2-
authors = ["Johnathan Stevers <[email protected]>"]
2+
authors = [
3+
"Johnathan Stevers <[email protected]>",
4+
"Glen Henri J. De Cauwsemaecker <[email protected]>",
5+
]
36
categories = ["web-programming"]
47
description = "Datastar is the Rust implementation of the [Datastar](https://data-star.dev) SDK."
5-
edition = "2021"
8+
edition = "2024"
69
homepage = "https://data-star.dev"
710
keywords = ["datastar", "web", "backend"]
811
license = "MIT OR Apache-2.0"
912
name = "datastar"
1013
readme = "README.md"
1114
repository = "https://github.com/starfederation/datastar-rs"
1215
version = "0.1.0"
16+
rust-version = "1.85.0"
1317

1418
[dev-dependencies]
1519
async-stream = { version = "0.3.6", default-features = false }
16-
serde = { version = "1.0.217", default-features = false, features = ["derive"] }
17-
serde_json = { version = "1.0.138", default-features = false, features = [
18-
"std",
19-
] }
20+
serde = { version = "1", default-features = false, features = ["derive"] }
21+
serde_json = { version = "1", default-features = false, features = ["std"] }
2022
tokio = { version = "1.43.0", features = ["full"] }
2123
axum = { version = "0.8.1" }
2224
rocket = { version = "0.5.1", features = ["json"] }
25+
rama = { version = "0.2.0-alpha.10", features = ["http-full"] }
2326

2427

2528
[dependencies]
29+
matchit = "0.8.4"
2630
axum = { version = "0.8.1", default-features = false, optional = true, features = [
2731
"query",
2832
"tokio",
2933
] }
30-
futures-util = { version = "0.3.31", default-features = false }
31-
http-body = { version = "1.0.1", default-features = false, optional = true }
32-
pin-project-lite = { version = "0.2.16", default-features = false, optional = true }
34+
futures-util = { version = "0.3", default-features = false }
35+
http-body = { version = "1.0", default-features = false, optional = true }
36+
pin-project-lite = { version = "0.2", default-features = false, optional = true }
3337
rocket = { version = "0.5.1", default-features = false, optional = true }
34-
serde = { version = "1.0.217", default-features = false, optional = true, features = [
38+
rama = { version = "0.2.0-alpha.11", default-features = false, optional = true, features = [
39+
"http",
40+
] }
41+
serde = { version = "1", default-features = false, optional = true, features = [
3542
"derive",
3643
] }
37-
serde_json = { version = "1.0.138", default-features = false, optional = true, features = [
44+
serde_json = { version = "1", default-features = false, optional = true, features = [
3845
"std",
3946
] }
40-
sync_wrapper = { version = "1.0.2", default-features = false, optional = true }
47+
sync_wrapper = { version = "1", default-features = false, optional = true }
48+
bytes = { version = "1", default-features = false, optional = true }
4149

4250

4351
[features]
@@ -51,6 +59,14 @@ axum = [
5159
]
5260
http2 = []
5361
rocket = ["dep:rocket"]
62+
rama = [
63+
"dep:rama",
64+
"dep:serde",
65+
"dep:serde_json",
66+
"dep:pin-project-lite",
67+
"dep:bytes",
68+
"dep:sync_wrapper",
69+
]
5470

5571
[profile.dev]
5672
opt-level = 1

sdk/rust/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Datastar Rust SDK
22

3-
An implementation of the Datastar SDK in Rust with framework integration for Axum and Rocket.
3+
An implementation of the Datastar SDK in Rust with framework integration for Axum, Rocket and Rama.
44

55
# Usage
66

@@ -15,4 +15,4 @@ Sse(stream! {
1515
// Merges signals into the signals.
1616
yield MergeSignals::new("{response: '', answer: 'bread'}").into();
1717
})
18-
```
18+
```

sdk/rust/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
#[cfg(feature = "axum")]
77
pub mod axum;
8+
#[cfg(feature = "rama")]
9+
pub mod rama;
810
#[cfg(feature = "rocket")]
911
pub mod rocket;
1012

@@ -23,6 +25,8 @@ mod consts;
2325
pub mod prelude {
2426
#[cfg(feature = "axum")]
2527
pub use crate::axum::ReadSignals;
28+
#[cfg(all(feature = "rama", not(feature = "axum")))]
29+
pub use crate::rama::ReadSignals;
2630
pub use crate::{
2731
consts::FragmentMergeMode, execute_script::ExecuteScript, merge_fragments::MergeFragments,
2832
merge_signals::MergeSignals, remove_fragments::RemoveFragments,

0 commit comments

Comments
 (0)