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:
1 parent
44f3047780
commit
86d1dba699
5 files changed
+125
-43
No files matched your search
@@ -13,7 +13,7 @@ use dioxus::html::input_data::keyboard_types::Key;
|
|||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
LaunchBuilder::new()
|
LaunchBuilder::desktop()
|
||||||
.with_cfg(desktop!({
|
.with_cfg(desktop!({
|
||||||
use dioxus::desktop::{Config, LogicalSize, WindowBuilder};
|
use dioxus::desktop::{Config, LogicalSize, WindowBuilder};
|
||||||
Config::new().with_window(
|
Config::new().with_window(
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
LaunchBuilder::desktop()
|
LaunchBuilder::new()
|
||||||
.with_cfg(
|
.with_cfg(
|
||||||
dioxus::desktop::Config::new().with_custom_index(
|
dioxus::desktop::Config::new().with_custom_index(
|
||||||
r#"
|
r#"
|
||||||
|
|||||||
@@ -15,14 +15,14 @@ use dioxus::desktop::{Config, LogicalSize, WindowBuilder};
|
|||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
LaunchBuilder::desktop()
|
LaunchBuilder::new()
|
||||||
.with_cfg(
|
.with_cfg(desktop! {
|
||||||
Config::new().with_window(
|
Config::new().with_window(
|
||||||
WindowBuilder::new()
|
WindowBuilder::new()
|
||||||
.with_title("Doggo Fetcher")
|
.with_title("Doggo Fetcher")
|
||||||
.with_inner_size(LogicalSize::new(600.0, 800.0)),
|
.with_inner_size(LogicalSize::new(600.0, 800.0)),
|
||||||
),
|
)
|
||||||
)
|
})
|
||||||
.launch(app)
|
.launch(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub fn server_only(input: TokenStream) -> TokenStream {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
quote! {
|
||||||
|| {}
|
{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
@@ -30,7 +30,7 @@ pub fn client(input: TokenStream) -> TokenStream {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
quote! {
|
||||||
|| {}
|
{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
@@ -45,7 +45,7 @@ pub fn web(input: TokenStream) -> TokenStream {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
quote! {
|
||||||
|| {}
|
{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
@@ -60,7 +60,22 @@ pub fn desktop(input: TokenStream) -> TokenStream {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
quote! {
|
||||||
|| {}
|
{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn mobile(input: TokenStream) -> TokenStream {
|
||||||
|
if cfg!(feature = "mobile") {
|
||||||
|
let input = TokenStream2::from(input);
|
||||||
|
quote! {
|
||||||
|
#input
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
@@ -75,7 +90,7 @@ pub fn fullstack(input: TokenStream) -> TokenStream {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
quote! {
|
||||||
|| {}
|
{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
@@ -90,7 +105,7 @@ pub fn ssr(input: TokenStream) -> TokenStream {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
quote! {
|
||||||
|| {}
|
{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
@@ -105,7 +120,7 @@ pub fn liveview(input: TokenStream) -> TokenStream {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
quote! {
|
||||||
|| {}
|
{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
//! Launch helper macros for fullstack apps
|
//! Launch helper macros for fullstack apps
|
||||||
#![allow(clippy::new_without_default)]
|
#![allow(clippy::new_without_default)]
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
|
use dioxus_config_macro::*;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
@@ -11,7 +12,7 @@ pub struct LaunchBuilder<Cfg: 'static = (), ContextFn: ?Sized = ValidContext> {
|
|||||||
launch_fn: LaunchFn<Cfg, ContextFn>,
|
launch_fn: LaunchFn<Cfg, ContextFn>,
|
||||||
contexts: Vec<Box<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);
|
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> {
|
impl<Cfg: Default + 'static, ContextFn: ?Sized> LaunchBuilder<Cfg, ContextFn> {
|
||||||
/// Provide a platform-specific config to the builder.
|
/// Provide a platform-specific config to the builder.
|
||||||
pub fn with_cfg<CG: 'static>(mut self, config: impl Into<Option<CG>>) -> Self {
|
pub fn with_cfg(mut self, config: impl TryIntoConfig<Cfg>) -> Self {
|
||||||
if let Some(config) = config.into() {
|
self.platform_config = self.platform_config.or(config.into_config());
|
||||||
self.platform_config = Some(Box::new(config));
|
|
||||||
}
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Launch your application.
|
/// Launch your application.
|
||||||
pub fn launch(self, app: fn() -> Element) {
|
pub fn launch(self, app: fn() -> Element) {
|
||||||
let cfg: Box<Cfg> = self
|
let cfg = self.platform_config.unwrap_or_default();
|
||||||
.platform_config
|
|
||||||
.and_then(|c| c.downcast().ok())
|
|
||||||
.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 {
|
mod current_platform {
|
||||||
#[cfg(all(feature = "desktop", not(feature = "fullstack")))]
|
macro_rules! if_else_cfg {
|
||||||
pub use dioxus_desktop::launch::*;
|
(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")))]
|
#[cfg(any(feature = "desktop", feature = "mobile"))]
|
||||||
pub use dioxus_mobile::launch::*;
|
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")]
|
#[cfg(feature = "fullstack")]
|
||||||
pub use dioxus_fullstack::launch::*;
|
pub use dioxus_fullstack::launch::*;
|
||||||
|
|
||||||
#[cfg(all(
|
#[cfg(feature = "web")]
|
||||||
feature = "web",
|
if_else_cfg! {
|
||||||
not(any(feature = "desktop", feature = "mobile", feature = "fullstack"))
|
if not(any(feature = "desktop", feature = "mobile", feature = "fullstack")) {
|
||||||
))]
|
pub use dioxus_web::launch::*;
|
||||||
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(
|
#[cfg(feature = "liveview")]
|
||||||
feature = "liveview",
|
if_else_cfg! {
|
||||||
not(any(
|
if
|
||||||
feature = "web",
|
not(any(
|
||||||
feature = "desktop",
|
feature = "web",
|
||||||
feature = "mobile",
|
feature = "desktop",
|
||||||
feature = "fullstack"
|
feature = "mobile",
|
||||||
))
|
feature = "fullstack"
|
||||||
))]
|
))
|
||||||
pub use dioxus_liveview::launch::*;
|
{
|
||||||
|
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(
|
#[cfg(not(any(
|
||||||
feature = "liveview",
|
feature = "liveview",
|
||||||
@@ -210,7 +277,7 @@ pub fn launch(app: fn() -> Element) {
|
|||||||
#[cfg_attr(docsrs, doc(cfg(feature = "web")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "web")))]
|
||||||
/// Launch your web application without any additional configuration. See [`LaunchBuilder`] for more options.
|
/// Launch your web application without any additional configuration. See [`LaunchBuilder`] for more options.
|
||||||
pub fn launch_web(app: fn() -> Element) {
|
pub fn launch_web(app: fn() -> Element) {
|
||||||
LaunchBuilder::web().launch(app)
|
LaunchBuilder::new().launch(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "desktop")]
|
#[cfg(feature = "desktop")]
|
||||||
|
|||||||
Reference in new issue
Block a user