improve quality of rust sdk and add tooling
also bump version to 0.1.2 - add makefile with all commands for rust sdk developers to run all relevant checks and test, which also auto formatting of code and toml deps - fixed broken clippy rules (this also required fixing some stuff in consts) Also fixed the docs.rs attributes to ensure _all_ modules and symbols get published in docs, instead of only those that are available in default features (which was missing the framework specific stuff in docs) Only nitpick issue left: in generated code (consts.rs) some descriptions can contain 'html' code which is not escaped, pretty certain this html will be rendered in docs.rs as rust docs renders docs as markdown (which includes html), but given that's auto generated I have left that for now as-is.
This commit is contained in:
parent
47a095f04a
commit
0eb448570e
|
@ -1,8 +1,13 @@
|
|||
{%- func rustConsts(data *ConstTemplateData) -%}
|
||||
//! Datastar constants
|
||||
#![allow(rustdoc::invalid_html_tags)]
|
||||
|
||||
// {%s data.DoNotEdit %}
|
||||
|
||||
pub const _DATASTAR_KEY: &str = "{%s data.DatastarKey %}";
|
||||
pub const _VERSION: &str = "{%s data.Version %}";
|
||||
#[expect(unused)]
|
||||
pub(crate) const DATASTAR_KEY: &str = "{%s data.DatastarKey %}";
|
||||
#[expect(unused)]
|
||||
pub(crate) const VERSION: &str = "{%s data.Version %}";
|
||||
|
||||
// #region Defaults
|
||||
|
||||
|
@ -19,7 +24,7 @@ pub const DEFAULT_{%s d.Name.ScreamingSnake %}: u64 = {%d durationToMs(d.Duratio
|
|||
|
||||
{%- for _, s := range data.DefaultStrings -%}
|
||||
/// {%s= s.Description %}
|
||||
pub const DEFAULT_{%s s.Name.ScreamingSnake %}: &str = "{%s s.Value %}";
|
||||
pub(crate) const DEFAULT_{%s s.Name.ScreamingSnake %}: &str = "{%s s.Value %}";
|
||||
{%- endfor -%}
|
||||
|
||||
// #endregion
|
||||
|
@ -27,7 +32,7 @@ pub const DEFAULT_{%s s.Name.ScreamingSnake %}: &str = "{%s s.Value %}";
|
|||
// #region Datalines
|
||||
|
||||
{%- for _, literal := range data.DatalineLiterals -%}
|
||||
pub const {%s literal.ScreamingSnake %}_DATALINE_LITERAL: &str = "{%s literal.Camel %}";
|
||||
pub(crate) const {%s literal.ScreamingSnake %}_DATALINE_LITERAL: &str = "{%s literal.Camel %}";
|
||||
{%- endfor -%}
|
||||
|
||||
// #endregion
|
||||
|
@ -36,7 +41,7 @@ pub const {%s literal.ScreamingSnake %}_DATALINE_LITERAL: &str = "{%s literal.Ca
|
|||
|
||||
{%- for _, b := range data.DefaultBools -%}
|
||||
/// {%s= b.Description %}
|
||||
pub const DEFAULT_{%s b.Name.ScreamingSnake %}: bool = {%v b.Value %};
|
||||
pub(crate) const DEFAULT_{%s b.Name.ScreamingSnake %}: bool = {%v b.Value %};
|
||||
{%- endfor -%}
|
||||
|
||||
// #endregion
|
||||
|
@ -58,7 +63,7 @@ pub enum {%s enum.Name.Pascal %} {
|
|||
|
||||
impl {%s enum.Name.Pascal %} {
|
||||
/// Returns the [`{%s enum.Name.Pascal %}`] as a string.
|
||||
pub const fn as_str(&self) -> &str {
|
||||
pub(crate) const fn as_str(&self) -> &str {
|
||||
match self {
|
||||
{%- for _, entry := range enum.Values -%}
|
||||
Self::{%s entry.Name.Pascal %} => "{%s entry.Value %}",
|
||||
|
@ -70,4 +75,4 @@ impl {%s enum.Name.Pascal %} {
|
|||
// #endregion
|
||||
|
||||
// #endregion
|
||||
{%- endfunc -%}
|
||||
{%- endfunc -%}
|
||||
|
|
|
@ -4,40 +4,66 @@ authors = [
|
|||
"Glen Henri J. De Cauwsemaecker <glen@plabayo.tech>",
|
||||
]
|
||||
categories = ["web-programming"]
|
||||
description = "Datastar is the Rust implementation of the [Datastar](https://data-star.dev) SDK."
|
||||
description = "Datastar SDK for Rust"
|
||||
documentation = "https://docs.rs/datastar"
|
||||
edition = "2024"
|
||||
homepage = "https://data-star.dev"
|
||||
keywords = ["datastar", "web", "backend"]
|
||||
keywords = ["datastar", "web", "backend", "axum", "rama", "rocket"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
name = "datastar"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/starfederation/datastar-rs"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
rust-version = "1.85.0"
|
||||
|
||||
[dev-dependencies]
|
||||
async-stream = { version = "0.3.6", default-features = false }
|
||||
serde = { version = "1", default-features = false, features = ["derive"] }
|
||||
serde_json = { version = "1", default-features = false, features = ["std"] }
|
||||
tokio = { version = "1.43.0", features = ["full"] }
|
||||
axum = { version = "0.8.1" }
|
||||
rocket = { version = "0.5.1", features = ["json"] }
|
||||
rama = { version = "0.2.0-alpha.10", features = ["http-full"] }
|
||||
[lints.rust]
|
||||
unreachable_pub = "deny"
|
||||
elided_lifetimes_in_paths = "allow"
|
||||
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fuzzing)'] }
|
||||
|
||||
[lints.clippy]
|
||||
all = { level = "warn", priority = -1 }
|
||||
todo = "warn"
|
||||
empty_enum = "warn"
|
||||
enum_glob_use = "warn"
|
||||
mem_forget = "warn"
|
||||
unused_self = "warn"
|
||||
filter_map_next = "warn"
|
||||
needless_continue = "warn"
|
||||
needless_borrow = "warn"
|
||||
match_wildcard_for_single_variants = "warn"
|
||||
if_let_mutex = "warn"
|
||||
await_holding_lock = "warn"
|
||||
match_on_vec_items = "warn"
|
||||
imprecise_flops = "warn"
|
||||
suboptimal_flops = "warn"
|
||||
lossy_float_literal = "warn"
|
||||
rest_pat_in_fully_bound_structs = "warn"
|
||||
fn_params_excessive_bools = "warn"
|
||||
exit = "warn"
|
||||
inefficient_to_string = "warn"
|
||||
linkedlist = "warn"
|
||||
macro_use_imports = "warn"
|
||||
option_option = "warn"
|
||||
verbose_file_reads = "warn"
|
||||
unnested_or_patterns = "warn"
|
||||
str_to_string = "warn"
|
||||
type_complexity = "allow"
|
||||
|
||||
[dependencies]
|
||||
matchit = "0.8.4"
|
||||
axum = { version = "0.8.1", default-features = false, optional = true, features = [
|
||||
"query",
|
||||
"tokio",
|
||||
] }
|
||||
bytes = { version = "1", default-features = false, optional = true }
|
||||
futures-util = { version = "0.3", default-features = false }
|
||||
http-body = { version = "1.0", default-features = false, optional = true }
|
||||
matchit = "0.8.4"
|
||||
pin-project-lite = { version = "0.2", default-features = false, optional = true }
|
||||
rocket = { version = "0.5.1", default-features = false, optional = true }
|
||||
rama = { version = "0.2.0-alpha.11", default-features = false, optional = true, features = [
|
||||
"http",
|
||||
] }
|
||||
rocket = { version = "0.5.1", default-features = false, optional = true }
|
||||
serde = { version = "1", default-features = false, optional = true, features = [
|
||||
"derive",
|
||||
] }
|
||||
|
@ -45,8 +71,15 @@ serde_json = { version = "1", default-features = false, optional = true, feature
|
|||
"std",
|
||||
] }
|
||||
sync_wrapper = { version = "1", default-features = false, optional = true }
|
||||
bytes = { version = "1", default-features = false, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
async-stream = { version = "0.3.6", default-features = false }
|
||||
axum = { version = "0.8.1" }
|
||||
rama = { version = "0.2.0-alpha.11", features = ["http-full"] }
|
||||
rocket = { version = "0.5.1", features = ["json"] }
|
||||
serde = { version = "1", default-features = false, features = ["derive"] }
|
||||
serde_json = { version = "1", default-features = false, features = ["std"] }
|
||||
tokio = { version = "1.43.0", features = ["full"] }
|
||||
|
||||
[features]
|
||||
axum = [
|
||||
|
@ -77,3 +110,7 @@ opt-level = 3
|
|||
[profile.release]
|
||||
codegen-units = 1
|
||||
lto = "thin"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
.PHONY: all
|
||||
|
||||
all:
|
||||
@echo "Usage:"
|
||||
@echo "fmt - run the rust formatter"
|
||||
@echo "sort - sort TOML dependencies"
|
||||
@echo "lint - combine fmt+sort"
|
||||
@echo "check - shallow check of rust code (pre-compile)"
|
||||
@echo "clippy - run clippy checks"
|
||||
@echo "doc - doc checks"
|
||||
@echo "hack - test feature matrix compatibility"
|
||||
@echo "test - run all unit and doc tests"
|
||||
@echo "qa - combine lint+check+clippy+doc+hack+test"
|
||||
@echo "hello-axum - run hello-world example using the Axum framework"
|
||||
@echo "hello-rama - run hello-world example using the Rama framework"
|
||||
@echo "hello-rocket - run hello-world example using the Rocket framework"
|
||||
.PHONY:
|
||||
|
||||
fmt:
|
||||
cargo fmt --all
|
||||
|
||||
sort:
|
||||
cargo sort --grouped
|
||||
|
||||
lint: fmt sort
|
||||
|
||||
check:
|
||||
cargo check --all-targets --all-features
|
||||
|
||||
clippy:
|
||||
cargo clippy --all-targets --all-features
|
||||
|
||||
doc:
|
||||
RUSTDOCFLAGS="-D rustdoc::broken-intra-doc-links" cargo doc --all-features --no-deps
|
||||
|
||||
hack:
|
||||
cargo hack check --each-feature --no-dev-deps --workspace
|
||||
|
||||
test:
|
||||
cargo test --all-features --workspace
|
||||
|
||||
qa: lint check clippy doc test
|
||||
|
||||
hello-axum:
|
||||
cd ../../examples/rust/axum/hello-world && cargo run
|
||||
|
||||
hello-rama:
|
||||
cd ../../examples/rust/rama/hello-world && cargo run
|
||||
|
||||
hello-rocket:
|
||||
cd ../../examples/rust/rocket/hello-world && cargo run
|
|
@ -1,6 +1,7 @@
|
|||
# Datastar Rust SDK
|
||||
|
||||
An implementation of the Datastar SDK in Rust with framework integration for Axum, Rocket and Rama.
|
||||
An implementation of the [Datastar] SDK in Rust
|
||||
with framework integration for [Axum], [Rocket] and [Rama].
|
||||
|
||||
# Usage
|
||||
|
||||
|
@ -16,3 +17,8 @@ Sse(stream! {
|
|||
yield MergeSignals::new("{response: '', answer: 'bread'}").into();
|
||||
})
|
||||
```
|
||||
|
||||
[Datastar]: https://data-star.dev
|
||||
[Axum]: https://github.com/tokio-rs/axum
|
||||
[Rocket]: https://github.com/rwf2/rocket
|
||||
[Rama]: https://github.com/plabayo/rama
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! Axum integration for Datastar.
|
||||
|
||||
use {
|
||||
crate::{prelude::DatastarEvent, Sse, TrySse},
|
||||
crate::{Sse, TrySse, prelude::DatastarEvent},
|
||||
axum::{
|
||||
body::{Body, Bytes, HttpBody},
|
||||
extract::{FromRequest, Query, Request},
|
||||
|
@ -16,7 +16,7 @@ use {
|
|||
futures_util::{Stream, StreamExt},
|
||||
http_body::Frame,
|
||||
pin_project_lite::pin_project,
|
||||
serde::{de::DeserializeOwned, Deserialize},
|
||||
serde::{Deserialize, de::DeserializeOwned},
|
||||
sync_wrapper::SyncWrapper,
|
||||
};
|
||||
|
||||
|
@ -162,9 +162,9 @@ mod tests {
|
|||
testing::{self, Signals},
|
||||
},
|
||||
axum::{
|
||||
Router,
|
||||
response::IntoResponse,
|
||||
routing::{get, post},
|
||||
Router,
|
||||
},
|
||||
tokio::net::TcpListener,
|
||||
};
|
||||
|
@ -174,6 +174,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore]
|
||||
async fn sdk_test() -> Result<(), Box<dyn core::error::Error>> {
|
||||
let listener = TcpListener::bind("127.0.0.1:3000").await?;
|
||||
let app = Router::new()
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
//! Datastar constants
|
||||
#![allow(rustdoc::invalid_html_tags)]
|
||||
|
||||
// This is auto-generated by Datastar. DO NOT EDIT.
|
||||
|
||||
pub const _DATASTAR_KEY: &str = "datastar";
|
||||
pub const _VERSION: &str = "1.0.0-beta.11";
|
||||
#[expect(unused)]
|
||||
pub(crate) const DATASTAR_KEY: &str = "datastar";
|
||||
#[expect(unused)]
|
||||
pub(crate) const VERSION: &str = "1.0.0-beta.11";
|
||||
|
||||
// #region Defaults
|
||||
|
||||
|
@ -15,40 +20,40 @@ pub const DEFAULT_SSE_RETRY_DURATION: u64 = 1000;
|
|||
// #region Default strings
|
||||
|
||||
/// The default attributes for <script/> element use when executing scripts. It is a set of key-value pairs delimited by a newline \\n character.
|
||||
pub const DEFAULT_EXECUTE_SCRIPT_ATTRIBUTES: &str = "type module";
|
||||
pub(crate) const DEFAULT_EXECUTE_SCRIPT_ATTRIBUTES: &str = "type module";
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region Datalines
|
||||
|
||||
pub const SELECTOR_DATALINE_LITERAL: &str = "selector";
|
||||
pub const MERGE_MODE_DATALINE_LITERAL: &str = "mergeMode";
|
||||
pub const FRAGMENTS_DATALINE_LITERAL: &str = "fragments";
|
||||
pub const USE_VIEW_TRANSITION_DATALINE_LITERAL: &str = "useViewTransition";
|
||||
pub const SIGNALS_DATALINE_LITERAL: &str = "signals";
|
||||
pub const ONLY_IF_MISSING_DATALINE_LITERAL: &str = "onlyIfMissing";
|
||||
pub const PATHS_DATALINE_LITERAL: &str = "paths";
|
||||
pub const SCRIPT_DATALINE_LITERAL: &str = "script";
|
||||
pub const ATTRIBUTES_DATALINE_LITERAL: &str = "attributes";
|
||||
pub const AUTO_REMOVE_DATALINE_LITERAL: &str = "autoRemove";
|
||||
pub(crate) const SELECTOR_DATALINE_LITERAL: &str = "selector";
|
||||
pub(crate) const MERGE_MODE_DATALINE_LITERAL: &str = "mergeMode";
|
||||
pub(crate) const FRAGMENTS_DATALINE_LITERAL: &str = "fragments";
|
||||
pub(crate) const USE_VIEW_TRANSITION_DATALINE_LITERAL: &str = "useViewTransition";
|
||||
pub(crate) const SIGNALS_DATALINE_LITERAL: &str = "signals";
|
||||
pub(crate) const ONLY_IF_MISSING_DATALINE_LITERAL: &str = "onlyIfMissing";
|
||||
pub(crate) const PATHS_DATALINE_LITERAL: &str = "paths";
|
||||
pub(crate) const SCRIPT_DATALINE_LITERAL: &str = "script";
|
||||
pub(crate) const ATTRIBUTES_DATALINE_LITERAL: &str = "attributes";
|
||||
pub(crate) const AUTO_REMOVE_DATALINE_LITERAL: &str = "autoRemove";
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region Default booleans
|
||||
|
||||
/// Should fragments be merged using the ViewTransition API?
|
||||
pub const DEFAULT_FRAGMENTS_USE_VIEW_TRANSITIONS: bool = false;
|
||||
pub(crate) const DEFAULT_FRAGMENTS_USE_VIEW_TRANSITIONS: bool = false;
|
||||
/// Should a given set of signals merge if they are missing?
|
||||
pub const DEFAULT_MERGE_SIGNALS_ONLY_IF_MISSING: bool = false;
|
||||
pub(crate) const DEFAULT_MERGE_SIGNALS_ONLY_IF_MISSING: bool = false;
|
||||
/// Should script element remove itself after execution?
|
||||
pub const DEFAULT_EXECUTE_SCRIPT_AUTO_REMOVE: bool = true;
|
||||
pub(crate) const DEFAULT_EXECUTE_SCRIPT_AUTO_REMOVE: bool = true;
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region Enums
|
||||
|
||||
/// The mode in which a fragment is merged into the DOM.
|
||||
#[derive(Default,Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum FragmentMergeMode {
|
||||
/// Morphs the fragment into the existing element using idiomorph.
|
||||
#[default]
|
||||
|
@ -71,7 +76,7 @@ pub enum FragmentMergeMode {
|
|||
|
||||
impl FragmentMergeMode {
|
||||
/// Returns the [`FragmentMergeMode`] as a string.
|
||||
pub const fn as_str(&self) -> &str {
|
||||
pub(crate) const fn as_str(&self) -> &str {
|
||||
match self {
|
||||
Self::Morph => "morph",
|
||||
Self::Inner => "inner",
|
||||
|
@ -101,7 +106,7 @@ pub enum EventType {
|
|||
|
||||
impl EventType {
|
||||
/// Returns the [`EventType`] as a string.
|
||||
pub const fn as_str(&self) -> &str {
|
||||
pub(crate) const fn as_str(&self) -> &str {
|
||||
match self {
|
||||
Self::MergeFragments => "datastar-merge-fragments",
|
||||
Self::MergeSignals => "datastar-merge-signals",
|
||||
|
@ -113,4 +118,4 @@ impl EventType {
|
|||
}
|
||||
// #endregion
|
||||
|
||||
// #endregion
|
||||
// #endregion
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! [`ExecuteScript`] executes JavaScript in the browser.
|
||||
|
||||
use {
|
||||
crate::{consts, DatastarEvent},
|
||||
crate::{DatastarEvent, consts},
|
||||
core::time::Duration,
|
||||
};
|
||||
|
||||
|
@ -27,10 +27,10 @@ use {
|
|||
pub struct ExecuteScript {
|
||||
/// `id` can be used by the backend to replay events.
|
||||
/// This is part of the SSE spec and is used to tell the browser how to handle the event.
|
||||
/// For more details see https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#id
|
||||
/// For more details see <https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#id>
|
||||
pub id: Option<String>,
|
||||
/// `retry` is part of the SSE spec and is used to tell the browser how long to wait before reconnecting if the connection is lost.
|
||||
/// For more details see https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#retry
|
||||
/// For more details see <https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#retry>
|
||||
pub retry: Duration,
|
||||
/// `script` is a string that represents the JavaScript to be executed by the browser.
|
||||
pub script: String,
|
||||
|
@ -49,7 +49,7 @@ impl ExecuteScript {
|
|||
retry: Duration::from_millis(consts::DEFAULT_SSE_RETRY_DURATION),
|
||||
script: script.into(),
|
||||
auto_remove: consts::DEFAULT_EXECUTE_SCRIPT_AUTO_REMOVE,
|
||||
attributes: vec![consts::DEFAULT_EXECUTE_SCRIPT_ATTRIBUTES.to_string()],
|
||||
attributes: vec![consts::DEFAULT_EXECUTE_SCRIPT_ATTRIBUTES.to_owned()],
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ pub mod remove_signals;
|
|||
#[cfg(test)]
|
||||
mod testing;
|
||||
|
||||
mod consts;
|
||||
pub mod consts;
|
||||
|
||||
/// The prelude for the `datastar` crate
|
||||
pub mod prelude {
|
||||
|
@ -28,9 +28,9 @@ pub mod prelude {
|
|||
#[cfg(all(feature = "rama", not(feature = "axum")))]
|
||||
pub use crate::rama::ReadSignals;
|
||||
pub use crate::{
|
||||
consts::FragmentMergeMode, execute_script::ExecuteScript, merge_fragments::MergeFragments,
|
||||
merge_signals::MergeSignals, remove_fragments::RemoveFragments,
|
||||
remove_signals::RemoveSignals, DatastarEvent, Sse, TrySse,
|
||||
DatastarEvent, Sse, TrySse, consts::FragmentMergeMode, execute_script::ExecuteScript,
|
||||
merge_fragments::MergeFragments, merge_signals::MergeSignals,
|
||||
remove_fragments::RemoveFragments, remove_signals::RemoveSignals,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -47,10 +47,10 @@ pub struct DatastarEvent {
|
|||
pub event: consts::EventType,
|
||||
/// `id` is can be used by the backend to replay events.
|
||||
/// This is part of the SSE spec and is used to tell the browser how to handle the event.
|
||||
/// For more details see https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#id
|
||||
/// For more details see <https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#id>
|
||||
pub id: Option<String>,
|
||||
/// `retry` is part of the SSE spec and is used to tell the browser how long to wait before reconnecting if the connection is lost.
|
||||
/// For more details see https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#retry
|
||||
/// For more details see <https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#retry>
|
||||
pub retry: Duration,
|
||||
/// `data` is the data that is sent with the event.
|
||||
pub data: Vec<String>,
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
use {
|
||||
crate::{
|
||||
consts::{self, FragmentMergeMode},
|
||||
DatastarEvent,
|
||||
consts::{self, FragmentMergeMode},
|
||||
},
|
||||
core::time::Duration,
|
||||
};
|
||||
|
@ -33,10 +33,10 @@ use {
|
|||
pub struct MergeFragments {
|
||||
/// `id` is can be used by the backend to replay events.
|
||||
/// This is part of the SSE spec and is used to tell the browser how to handle the event.
|
||||
/// For more details see https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#id
|
||||
/// For more details see <https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#id>
|
||||
pub id: Option<String>,
|
||||
/// `retry` is part of the SSE spec and is used to tell the browser how long to wait before reconnecting if the connection is lost.
|
||||
/// For more details see https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#retry
|
||||
/// For more details see <https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#retry>
|
||||
pub retry: Duration,
|
||||
/// The HTML fragments to merge into the DOM.
|
||||
pub fragments: String,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! [`MergeSignals`] sends one or more signals to the browser to be merged into the signals.
|
||||
|
||||
use {
|
||||
crate::{consts, DatastarEvent},
|
||||
crate::{DatastarEvent, consts},
|
||||
core::time::Duration,
|
||||
};
|
||||
|
||||
|
@ -25,10 +25,10 @@ use {
|
|||
pub struct MergeSignals {
|
||||
/// `id` can be used by the backend to replay events.
|
||||
/// This is part of the SSE spec and is used to tell the browser how to handle the event.
|
||||
/// For more details see https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#id
|
||||
/// For more details see <https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#id>
|
||||
pub id: Option<String>,
|
||||
/// `retry` is part of the SSE spec and is used to tell the browser how long to wait before reconnecting if the connection is lost.
|
||||
/// For more details see https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#retry
|
||||
/// For more details see <https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#retry>
|
||||
pub retry: Duration,
|
||||
/// `signals` is a JavaScript object or JSON string that will be sent to the browser to update signals in the signals.
|
||||
/// The data ***must*** evaluate to a valid JavaScript. It will be converted to signals by the Datastar client side.
|
||||
|
|
|
@ -8,11 +8,14 @@ use {
|
|||
bytes::Bytes,
|
||||
futures_util::{Stream, StreamExt},
|
||||
pin_project_lite::pin_project,
|
||||
rama::http::{
|
||||
Body, BodyExtractExt, IntoResponse, Method, Request, Response, StatusCode,
|
||||
dep::http_body::{Body as HttpBody, Frame},
|
||||
header,
|
||||
service::web::extract::{FromRequest, Query},
|
||||
rama::{
|
||||
error::BoxError,
|
||||
http::{
|
||||
Body, BodyExtractExt, IntoResponse, Method, Request, Response, StatusCode,
|
||||
dep::http_body::{Body as HttpBody, Frame},
|
||||
header,
|
||||
service::web::extract::{FromRequest, Query},
|
||||
},
|
||||
},
|
||||
serde::{Deserialize, de::DeserializeOwned},
|
||||
std::{
|
||||
|
@ -52,7 +55,7 @@ where
|
|||
impl<S, E> IntoResponse for TrySse<S>
|
||||
where
|
||||
S: Stream<Item = Result<DatastarEvent, E>> + Send + 'static,
|
||||
E: Into<Box<dyn std::error::Error + Send + Sync>>,
|
||||
E: Into<BoxError>,
|
||||
{
|
||||
fn into_response(self) -> Response {
|
||||
(
|
||||
|
@ -157,12 +160,13 @@ mod tests {
|
|||
use {
|
||||
super::Sse,
|
||||
crate::{
|
||||
prelude::ReadSignals,
|
||||
rama::ReadSignals,
|
||||
testing::{self, Signals},
|
||||
},
|
||||
rama::{
|
||||
error::BoxError,
|
||||
http::{IntoResponse, server::HttpServer, service::web::Router},
|
||||
net::address::SocketAddress,
|
||||
rt::Executor,
|
||||
},
|
||||
};
|
||||
|
@ -172,10 +176,11 @@ mod tests {
|
|||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore]
|
||||
async fn sdk_test() -> Result<(), BoxError> {
|
||||
HttpServer::auto(Executor::default())
|
||||
.listen(
|
||||
"127.0.0.1:3000",
|
||||
SocketAddress::local_ipv4(3000),
|
||||
Router::new().get("/test", test).post("/test", test),
|
||||
)
|
||||
.await?;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! [`RemoveFragments`] sends a selector to the browser to remove HTML fragments from the DOM.
|
||||
|
||||
use {
|
||||
crate::{consts, DatastarEvent},
|
||||
crate::{DatastarEvent, consts},
|
||||
core::time::Duration,
|
||||
};
|
||||
|
||||
|
@ -26,10 +26,10 @@ use {
|
|||
pub struct RemoveFragments {
|
||||
/// `id` can be used by the backend to replay events.
|
||||
/// This is part of the SSE spec and is used to tell the browser how to handle the event.
|
||||
/// For more details see https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#id
|
||||
/// For more details see <https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#id>
|
||||
pub id: Option<String>,
|
||||
/// `retry` is part of the SSE spec and is used to tell the browser how long to wait before reconnecting if the connection is lost.
|
||||
/// For more details see https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#retry
|
||||
/// For more details see <https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#retry>
|
||||
pub retry: Duration,
|
||||
/// `selector` is a CSS selector that represents the fragments to be removed from the DOM.
|
||||
/// The selector must be a valid CSS selector.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! [`RemoveSignals`] sends signals to the browser to be removed from the signals.
|
||||
|
||||
use {
|
||||
crate::{consts, DatastarEvent},
|
||||
crate::{DatastarEvent, consts},
|
||||
core::time::Duration,
|
||||
};
|
||||
|
||||
|
@ -23,10 +23,10 @@ use {
|
|||
pub struct RemoveSignals {
|
||||
/// `id` can be used by the backend to replay events.
|
||||
/// This is part of the SSE spec and is used to tell the browser how to handle the event.
|
||||
/// For more details see https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#id
|
||||
/// For more details see <https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#id>
|
||||
pub id: Option<String>,
|
||||
/// `retry` is part of the SSE spec and is used to tell the browser how long to wait before reconnecting if the connection is lost.
|
||||
/// For more details see https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#retry
|
||||
/// For more details see <https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#retry>
|
||||
pub retry: Duration,
|
||||
/// `paths` is a list of strings that represent the signal paths to be removed from the signals.
|
||||
/// The paths ***must*** be valid . delimited paths to signals within the signals.
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
//! Rocket integration for Datastar.
|
||||
|
||||
use {
|
||||
crate::{prelude::DatastarEvent, Sse, TrySse},
|
||||
crate::{Sse, TrySse, prelude::DatastarEvent},
|
||||
core::error::Error,
|
||||
futures_util::{Stream, StreamExt},
|
||||
rocket::{
|
||||
http::ContentType,
|
||||
response::{self, stream::ReaderStream, Responder},
|
||||
Request, Response,
|
||||
http::ContentType,
|
||||
response::{self, Responder, stream::ReaderStream},
|
||||
},
|
||||
std::io::Cursor,
|
||||
};
|
||||
|
@ -60,14 +60,15 @@ where
|
|||
mod tests {
|
||||
use {
|
||||
crate::{
|
||||
testing::{self, Signals},
|
||||
DatastarEvent, Sse,
|
||||
testing::{self, Signals},
|
||||
},
|
||||
futures_util::Stream,
|
||||
rocket::{get, post, routes, serde::json::Json},
|
||||
};
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore]
|
||||
async fn sdk_test() {
|
||||
rocket::build()
|
||||
.mount("/", routes![get_test, post_test])
|
||||
|
|
|
@ -12,7 +12,7 @@ use {
|
|||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(tag = "type", rename_all = "camelCase")]
|
||||
pub enum TestEvent {
|
||||
pub(crate) enum TestEvent {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
ExecuteScript {
|
||||
script: String,
|
||||
|
@ -53,11 +53,11 @@ pub enum TestEvent {
|
|||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Signals {
|
||||
pub(crate) struct Signals {
|
||||
pub events: Vec<TestEvent>,
|
||||
}
|
||||
|
||||
pub fn test(events: Vec<TestEvent>) -> impl Stream<Item = DatastarEvent> {
|
||||
pub(crate) fn test(events: Vec<TestEvent>) -> impl Stream<Item = DatastarEvent> + Send + 'static {
|
||||
stream! {
|
||||
for event in events {
|
||||
yield match event {
|
||||
|
|
Loading…
Reference in New Issue