Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ serde_json = "1.0.133"
shield = { path = "./packages/core/shield", version = "0.0.4" }
shield-actix = { path = "./packages/integrations/shield-actix", version = "0.0.4" }
shield-axum = { path = "./packages/integrations/shield-axum", version = "0.0.4" }
shield-bootstrap = { path = "./packages/styles/shield-bootstrap", version = "0.0.4" }
shield-credentials = { path = "./packages/methods/shield-credentials", version = "0.0.4" }
shield-diesel = { path = "./packages/storage/shield-diesel", version = "0.0.4" }
shield-dioxus = { path = "./packages/integrations/shield-dioxus", version = "0.0.4" }
Expand Down
1 change: 1 addition & 0 deletions examples/dioxus-axum/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ web = ["dioxus/web"]
axum = { workspace = true, optional = true }
dioxus = { workspace = true, features = ["router", "fullstack"] }
shield.workspace = true
shield-bootstrap = { workspace = true, features = ["dioxus"] }
shield-dioxus.workspace = true
shield-dioxus-axum = { workspace = true, optional = true }
shield-memory = { workspace = true, optional = true }
Expand Down
8 changes: 7 additions & 1 deletion examples/dioxus-axum/src/app.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use dioxus::prelude::*;
use dioxus::{document::Stylesheet, prelude::*};
use shield_dioxus::ShieldRouter;

use crate::home::Home;
Expand All @@ -17,6 +17,12 @@ enum Route {
#[component]
pub fn App() -> Element {
rsx! {
Stylesheet {
href: "https://cdn.jsdelivr.net/npm/bootstrap@5.3.7/dist/css/bootstrap.min.css",
integrity: "sha384-LN+7fdVzj6u52u30Kp6M/trliBMCMKTyK833zpbD+pXdCLuTusPj697FH4R/5mcr",
crossorigin: "anonymous"
}

main {
Router::<Route> {}
}
Expand Down
12 changes: 9 additions & 3 deletions examples/dioxus-axum/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ use crate::app::App;

#[cfg(not(feature = "server"))]
fn main() {
dioxus::launch(App);
use shield_bootstrap::dioxus::BootstrapStyle;

dioxus::LaunchBuilder::new()
.with_context(BootstrapStyle::default().context())
.launch(App)
}

#[cfg(feature = "server")]
Expand All @@ -19,7 +23,8 @@ async fn main() {
prelude::{DioxusRouterExt, *},
};
use shield::{Shield, ShieldOptions};
use shield_dioxus_axum::{ShieldLayer, provide_axum_integration};
use shield_bootstrap::dioxus::BootstrapStyle;
use shield_dioxus_axum::{DioxusAxumIntegration, ShieldLayer};
use shield_memory::{MemoryStorage, User};
use shield_oidc::{Keycloak, OidcMethod};
use tokio::net::TcpListener;
Expand Down Expand Up @@ -61,7 +66,8 @@ async fn main() {
let router = Router::new()
.serve_dioxus_application(
ServeConfigBuilder::new()
.context_provider(provide_axum_integration::<User>)
.context(DioxusAxumIntegration::<User>::default().context())
.context(BootstrapStyle::default().context())
.build()
.unwrap(),
App,
Expand Down
15 changes: 6 additions & 9 deletions packages/core/shield/src/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub const SIGN_OUT_ACTION_ID: &str = "sign-out";
pub trait Action<P: Provider>: ErasedAction + Send + Sync {
fn id(&self) -> String;

fn render(&self, provider: P) -> Form;
fn form(&self, provider: P) -> Form;

async fn call(
&self,
Expand All @@ -29,7 +29,7 @@ pub trait Action<P: Provider>: ErasedAction + Send + Sync {
pub trait ErasedAction: Send + Sync {
fn erased_id(&self) -> String;

fn erased_render(&self, provider: Box<dyn Any + Send + Sync>) -> Form;
fn erased_form(&self, provider: Box<dyn Any + Send + Sync>) -> Form;

async fn erased_call(
&self,
Expand All @@ -48,8 +48,8 @@ macro_rules! erased_action {
self.id()
}

fn erased_render(&self, provider: Box<dyn std::any::Any + Send + Sync>) -> $crate::Form {
self.render(*provider.downcast().expect("TODO"))
fn erased_form(&self, provider: Box<dyn std::any::Any + Send + Sync>) -> $crate::Form {
self.form(*provider.downcast().expect("TODO"))
}

async fn erased_call(
Expand Down Expand Up @@ -87,11 +87,8 @@ pub(crate) mod tests {
TEST_ACTION_ID.to_owned()
}

fn render(&self, _provider: TestProvider) -> Form {
Form {
inputs: vec![],
attributes: None,
}
fn form(&self, _provider: TestProvider) -> Form {
Form { inputs: vec![] }
}

async fn call(
Expand Down
78 changes: 32 additions & 46 deletions packages/core/shield/src/form.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,18 @@
use std::collections::HashMap;

use serde::{Deserialize, Serialize};

/// HTML [attribute](https://html.spec.whatwg.org/multipage/syntax.html#attributes-2).
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum Attribute {
Boolean(bool),
String(String),
}

/// HTML [form](https://html.spec.whatwg.org/multipage/forms.html#the-form-element).
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Form {
pub inputs: Vec<Input>,
pub attributes: Option<HashMap<String, Attribute>>,
}

/// HTML [input](https://html.spec.whatwg.org/multipage/input.html#the-input-element).
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Input {
pub name: String,
pub label: Option<String>,
pub r#type: InputType,
pub value: Option<String>,
pub attributes: Option<HashMap<String, Attribute>>,
}

/// HTML input [type](https://html.spec.whatwg.org/multipage/input.html#attr-input-type) and [attributes](https://html.spec.whatwg.org/multipage/input.html#input-type-attr-summary).
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum InputType {
Button(InputTypeButton),
Expand All @@ -53,12 +39,38 @@ pub enum InputType {
Week(InputTypeWeek),
}

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct InputTypeButton {
pub popovertarget: Option<String>,
pub popovertargetaction: Option<String>,
impl InputType {
pub fn as_str(&self) -> &'static str {
match self {
InputType::Button(_) => "button",
InputType::Checkbox(_) => "checkbox",
InputType::Color(_) => "color",
InputType::Date(_) => "date",
InputType::DatetimeLocal(_) => "datetime-local",
InputType::Email(_) => "email",
InputType::File(_) => "file",
InputType::Hidden(_) => "hidden",
InputType::Image(_) => "image",
InputType::Month(_) => "month",
InputType::Number(_) => "number",
InputType::Password(_) => "password",
InputType::Radio(_) => "radio",
InputType::Range(_) => "range",
InputType::Reset(_) => "reset",
InputType::Search(_) => "search",
InputType::Submit(_) => "submit",
InputType::Tel(_) => "tel",
InputType::Text(_) => "text",
InputType::Time(_) => "time",
InputType::Url(_) => "url",
InputType::Week(_) => "week",
}
}
}

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct InputTypeButton {}

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct InputTypeCheckbox {
pub checked: Option<bool>,
Expand Down Expand Up @@ -98,7 +110,6 @@ pub struct InputTypeDatetimeLocal {
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct InputTypeEmail {
pub autocomplete: Option<String>,
pub dirname: Option<String>,
pub list: Option<String>,
pub maxlength: Option<String>,
pub minlength: Option<String>,
Expand All @@ -120,21 +131,13 @@ pub struct InputTypeFile {
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct InputTypeHidden {
pub autocomplete: Option<String>,
pub dirname: Option<String>,
pub required: Option<bool>,
}

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct InputTypeImage {
pub alt: Option<String>,
pub formaction: Option<String>,
pub formenctype: Option<String>,
pub formmethod: Option<String>,
pub formnovalidate: Option<bool>,
pub formtarget: Option<String>,
pub height: Option<String>,
pub popovertarget: Option<String>,
pub popovertargetaction: Option<String>,
pub src: Option<String>,
pub width: Option<String>,
}
Expand Down Expand Up @@ -165,7 +168,6 @@ pub struct InputTypeNumber {
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct InputTypePassword {
pub autocomplete: Option<String>,
pub dirname: Option<String>,
pub maxlength: Option<String>,
pub minlength: Option<String>,
pub pattern: Option<String>,
Expand All @@ -191,15 +193,11 @@ pub struct InputTypeRange {
}

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct InputTypeReset {
pub popovertarget: Option<String>,
pub popovertargetaction: Option<String>,
}
pub struct InputTypeReset {}

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct InputTypeSearch {
pub autocomplete: Option<String>,
pub dirname: Option<String>,
pub list: Option<String>,
pub maxlength: Option<String>,
pub minlength: Option<String>,
Expand All @@ -211,21 +209,11 @@ pub struct InputTypeSearch {
}

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct InputTypeSubmit {
pub dirname: Option<String>,
pub formaction: Option<String>,
pub formenctype: Option<String>,
pub formmethod: Option<String>,
pub formnovalidate: Option<bool>,
pub formtarget: Option<String>,
pub popovertarget: Option<String>,
pub popovertargetaction: Option<String>,
}
pub struct InputTypeSubmit {}

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct InputTypeTel {
pub autocomplete: Option<String>,
pub dirname: Option<String>,
pub list: Option<String>,
pub maxlength: Option<String>,
pub minlength: Option<String>,
Expand All @@ -239,7 +227,6 @@ pub struct InputTypeTel {
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct InputTypeText {
pub autocomplete: Option<String>,
pub dirname: Option<String>,
pub list: Option<String>,
pub maxlength: Option<String>,
pub minlength: Option<String>,
Expand All @@ -264,7 +251,6 @@ pub struct InputTypeTime {
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct InputTypeUrl {
pub autocomplete: Option<String>,
pub dirname: Option<String>,
pub list: Option<String>,
pub maxlength: Option<String>,
pub minlength: Option<String>,
Expand Down
7 changes: 4 additions & 3 deletions packages/core/shield/src/shield.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{any::Any, collections::HashMap, sync::Arc};
use futures::future::try_join_all;

use crate::{
Form, error::ShieldError, method::ErasedMethod, options::ShieldOptions, storage::Storage,
error::ShieldError, form::Form, method::ErasedMethod, options::ShieldOptions, storage::Storage,
user::User,
};

Expand Down Expand Up @@ -73,7 +73,8 @@ impl<U: User> Shield<U> {
};

for provider in method.erased_providers().await? {
let form = action.erased_render(provider);
let form = action.erased_form(provider);

forms.push(form);
}
}
Expand All @@ -85,7 +86,7 @@ impl<U: User> Shield<U> {
#[cfg(test)]
mod tests {
use crate::{
ShieldOptions,
options::ShieldOptions,
storage::tests::{TEST_STORAGE_ID, TestStorage},
};

Expand Down
2 changes: 1 addition & 1 deletion packages/core/shield/src/shield_dyn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{any::Any, sync::Arc};

use async_trait::async_trait;

use crate::{Form, error::ShieldError, shield::Shield, user::User};
use crate::{error::ShieldError, form::Form, shield::Shield, user::User};

#[async_trait]
pub trait DynShield: Send + Sync {
Expand Down
10 changes: 6 additions & 4 deletions packages/integrations/shield-dioxus-axum/src/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ use shield_dioxus::{DioxusIntegration, DioxusIntegrationDyn};

pub struct DioxusAxumIntegration<U: User>(PhantomData<U>);

impl<U: User + Clone + 'static> DioxusAxumIntegration<U> {
pub fn context(self) -> DioxusIntegrationDyn {
DioxusIntegrationDyn::new(self)
}
}

impl<U: User> Default for DioxusAxumIntegration<U> {
fn default() -> Self {
Self(Default::default())
Expand All @@ -29,7 +35,3 @@ impl<U: User + Clone + 'static> DioxusIntegration for DioxusAxumIntegration<U> {
session
}
}

pub fn provide_axum_integration<U: User + Clone + 'static>() -> DioxusIntegrationDyn {
DioxusIntegrationDyn::new(DioxusAxumIntegration::<U>::default())
}
Loading