mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-10 06:34:20 +00:00
Check type of launch config (#2125)
* Check type of launch config * fix cargo check * compile when using an explicit platform with other platforms enabled * fix formatting * fix overlapping TryIntoConfig implementations * fix desktop headless tests --------- Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
parent
44f3047780
commit
86d1dba699
5 changed files with 125 additions and 43 deletions
|
@ -13,7 +13,7 @@ use dioxus::html::input_data::keyboard_types::Key;
|
|||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
LaunchBuilder::new()
|
||||
LaunchBuilder::desktop()
|
||||
.with_cfg(desktop!({
|
||||
use dioxus::desktop::{Config, LogicalSize, WindowBuilder};
|
||||
Config::new().with_window(
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
LaunchBuilder::desktop()
|
||||
LaunchBuilder::new()
|
||||
.with_cfg(
|
||||
dioxus::desktop::Config::new().with_custom_index(
|
||||
r#"
|
||||
|
|
|
@ -15,14 +15,14 @@ use dioxus::desktop::{Config, LogicalSize, WindowBuilder};
|
|||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
LaunchBuilder::desktop()
|
||||
.with_cfg(
|
||||
LaunchBuilder::new()
|
||||
.with_cfg(desktop! {
|
||||
Config::new().with_window(
|
||||
WindowBuilder::new()
|
||||
.with_title("Doggo Fetcher")
|
||||
.with_inner_size(LogicalSize::new(600.0, 800.0)),
|
||||
),
|
||||
)
|
||||
)
|
||||
})
|
||||
.launch(app)
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ pub fn server_only(input: TokenStream) -> TokenStream {
|
|||
}
|
||||
} else {
|
||||
quote! {
|
||||
|| {}
|
||||
{}
|
||||
}
|
||||
}
|
||||
.into()
|
||||
|
@ -30,7 +30,7 @@ pub fn client(input: TokenStream) -> TokenStream {
|
|||
}
|
||||
} else {
|
||||
quote! {
|
||||
|| {}
|
||||
{}
|
||||
}
|
||||
}
|
||||
.into()
|
||||
|
@ -45,7 +45,7 @@ pub fn web(input: TokenStream) -> TokenStream {
|
|||
}
|
||||
} else {
|
||||
quote! {
|
||||
|| {}
|
||||
{}
|
||||
}
|
||||
}
|
||||
.into()
|
||||
|
@ -60,7 +60,22 @@ pub fn desktop(input: TokenStream) -> TokenStream {
|
|||
}
|
||||
} else {
|
||||
quote! {
|
||||
|| {}
|
||||
{}
|
||||
}
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn mobile(input: TokenStream) -> TokenStream {
|
||||
if cfg!(feature = "mobile") {
|
||||
let input = TokenStream2::from(input);
|
||||
quote! {
|
||||
#input
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
{}
|
||||
}
|
||||
}
|
||||
.into()
|
||||
|
@ -75,7 +90,7 @@ pub fn fullstack(input: TokenStream) -> TokenStream {
|
|||
}
|
||||
} else {
|
||||
quote! {
|
||||
|| {}
|
||||
{}
|
||||
}
|
||||
}
|
||||
.into()
|
||||
|
@ -90,7 +105,7 @@ pub fn ssr(input: TokenStream) -> TokenStream {
|
|||
}
|
||||
} else {
|
||||
quote! {
|
||||
|| {}
|
||||
{}
|
||||
}
|
||||
}
|
||||
.into()
|
||||
|
@ -105,7 +120,7 @@ pub fn liveview(input: TokenStream) -> TokenStream {
|
|||
}
|
||||
} else {
|
||||
quote! {
|
||||
|| {}
|
||||
{}
|
||||
}
|
||||
}
|
||||
.into()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//! Launch helper macros for fullstack apps
|
||||
#![allow(clippy::new_without_default)]
|
||||
#![allow(unused)]
|
||||
use dioxus_config_macro::*;
|
||||
use std::any::Any;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
@ -11,7 +12,7 @@ pub struct LaunchBuilder<Cfg: 'static = (), ContextFn: ?Sized = ValidContext> {
|
|||
launch_fn: LaunchFn<Cfg, ContextFn>,
|
||||
contexts: Vec<Box<ContextFn>>,
|
||||
|
||||
platform_config: Option<Box<dyn Any>>,
|
||||
platform_config: Option<Cfg>,
|
||||
}
|
||||
|
||||
pub type LaunchFn<Cfg, Context> = fn(fn() -> Element, Vec<Box<Context>>, Cfg);
|
||||
|
@ -126,52 +127,118 @@ impl<Cfg> LaunchBuilder<Cfg, SendContext> {
|
|||
}
|
||||
}
|
||||
|
||||
/// A trait for converting a type into a platform-specific config:
|
||||
/// - A unit value will be converted into `None`
|
||||
/// - Any config will be converted into `Some(config)`
|
||||
/// - If the config is for another platform, it will be converted into `None`
|
||||
pub trait TryIntoConfig<Config = Self> {
|
||||
fn into_config(self) -> Option<Config>;
|
||||
}
|
||||
|
||||
// A config can always be converted into itself
|
||||
impl<Cfg> TryIntoConfig<Cfg> for Cfg {
|
||||
fn into_config(self) -> Option<Cfg> {
|
||||
Some(self)
|
||||
}
|
||||
}
|
||||
|
||||
// The unit type can be converted into the current platform config.
|
||||
// This makes it possible to use the `desktop!`, `web!`, etc macros with the launch API.
|
||||
#[cfg(any(
|
||||
feature = "liveview",
|
||||
feature = "desktop",
|
||||
feature = "mobile",
|
||||
feature = "web",
|
||||
feature = "fullstack"
|
||||
))]
|
||||
impl TryIntoConfig<current_platform::Config> for () {
|
||||
fn into_config(self) -> Option<current_platform::Config> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl<Cfg: Default + 'static, ContextFn: ?Sized> LaunchBuilder<Cfg, ContextFn> {
|
||||
/// Provide a platform-specific config to the builder.
|
||||
pub fn with_cfg<CG: 'static>(mut self, config: impl Into<Option<CG>>) -> Self {
|
||||
if let Some(config) = config.into() {
|
||||
self.platform_config = Some(Box::new(config));
|
||||
}
|
||||
pub fn with_cfg(mut self, config: impl TryIntoConfig<Cfg>) -> Self {
|
||||
self.platform_config = self.platform_config.or(config.into_config());
|
||||
self
|
||||
}
|
||||
|
||||
/// Launch your application.
|
||||
pub fn launch(self, app: fn() -> Element) {
|
||||
let cfg: Box<Cfg> = self
|
||||
.platform_config
|
||||
.and_then(|c| c.downcast().ok())
|
||||
.unwrap_or_default();
|
||||
let cfg = self.platform_config.unwrap_or_default();
|
||||
|
||||
(self.launch_fn)(app, self.contexts, *cfg)
|
||||
(self.launch_fn)(app, self.contexts, cfg)
|
||||
}
|
||||
}
|
||||
|
||||
/// Re-export the platform we expect the user wants
|
||||
///
|
||||
/// If multiple platforms are enabled, we use this priority (from highest to lowest):
|
||||
/// - `fullstack`
|
||||
/// - `desktop`
|
||||
/// - `mobile`
|
||||
/// - `web`
|
||||
/// - `liveview`
|
||||
mod current_platform {
|
||||
#[cfg(all(feature = "desktop", not(feature = "fullstack")))]
|
||||
pub use dioxus_desktop::launch::*;
|
||||
macro_rules! if_else_cfg {
|
||||
(if $attr:meta { $then:item } else { $else:item }) => {
|
||||
#[cfg($attr)]
|
||||
$then
|
||||
#[cfg(not($attr))]
|
||||
$else
|
||||
};
|
||||
}
|
||||
use crate::prelude::TryIntoConfig;
|
||||
|
||||
#[cfg(all(feature = "mobile", not(feature = "fullstack")))]
|
||||
pub use dioxus_mobile::launch::*;
|
||||
#[cfg(any(feature = "desktop", feature = "mobile"))]
|
||||
if_else_cfg! {
|
||||
if not(feature = "fullstack") {
|
||||
pub use dioxus_desktop::launch::*;
|
||||
} else {
|
||||
impl TryIntoConfig<crate::launch::current_platform::Config> for ::dioxus_desktop::Config {
|
||||
fn into_config(self) -> Option<crate::launch::current_platform::Config> {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "fullstack")]
|
||||
pub use dioxus_fullstack::launch::*;
|
||||
|
||||
#[cfg(all(
|
||||
feature = "web",
|
||||
not(any(feature = "desktop", feature = "mobile", feature = "fullstack"))
|
||||
))]
|
||||
pub use dioxus_web::launch::*;
|
||||
#[cfg(feature = "web")]
|
||||
if_else_cfg! {
|
||||
if not(any(feature = "desktop", feature = "mobile", feature = "fullstack")) {
|
||||
pub use dioxus_web::launch::*;
|
||||
} else {
|
||||
impl TryIntoConfig<crate::launch::current_platform::Config> for ::dioxus_web::Config {
|
||||
fn into_config(self) -> Option<crate::launch::current_platform::Config> {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
feature = "liveview",
|
||||
not(any(
|
||||
feature = "web",
|
||||
feature = "desktop",
|
||||
feature = "mobile",
|
||||
feature = "fullstack"
|
||||
))
|
||||
))]
|
||||
pub use dioxus_liveview::launch::*;
|
||||
#[cfg(feature = "liveview")]
|
||||
if_else_cfg! {
|
||||
if
|
||||
not(any(
|
||||
feature = "web",
|
||||
feature = "desktop",
|
||||
feature = "mobile",
|
||||
feature = "fullstack"
|
||||
))
|
||||
{
|
||||
pub use dioxus_liveview::launch::*;
|
||||
} else {
|
||||
impl<R: ::dioxus_liveview::LiveviewRouter> TryIntoConfig<crate::launch::current_platform::Config> for ::dioxus_liveview::Config<R> {
|
||||
fn into_config(self) -> Option<crate::launch::current_platform::Config> {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(
|
||||
feature = "liveview",
|
||||
|
@ -210,7 +277,7 @@ pub fn launch(app: fn() -> Element) {
|
|||
#[cfg_attr(docsrs, doc(cfg(feature = "web")))]
|
||||
/// Launch your web application without any additional configuration. See [`LaunchBuilder`] for more options.
|
||||
pub fn launch_web(app: fn() -> Element) {
|
||||
LaunchBuilder::web().launch(app)
|
||||
LaunchBuilder::new().launch(app)
|
||||
}
|
||||
|
||||
#[cfg(feature = "desktop")]
|
||||
|
|
Loading…
Reference in a new issue