uniui_build 0.0.6

Builds uniui applicatins for different targets
Documentation
/// The constant used as a css class name for the body tag for every page.
pub const BODY_THEME_CLASS_NAME: &str = "u_body_unique_forewer";

use ::uni_components::ui_page::UiPage;

#[doc(hidden)]
pub mod uni_components {
	pub use uni_components::*;
}

#[doc(hidden)]
pub mod log {
	pub use log::*;
}

#[doc(hidden)]
pub const RUN_FUNCTION_NAME: &'static str = "run";

#[doc(hidden)]
pub const TICK_FUNCTION_NAME: &'static str = "tick";

#[doc(hidden)]
pub const CLEANUP_FUNCTION_NAME: &'static str = "cleanup";

#[doc(hidden)]
pub fn android_module_name<T: std::fmt::Display>(fn_name: T) -> String {
	return format!("{}_android_start", fn_name);
}


mod build_cpp_qt;
pub use self::build_cpp_qt::build_x86_64_cpp_qt5;

mod build_wasm;

#[doc(hidden)]
pub use build_wasm::*;

#[cfg(feature = "android")]
mod build_android;

#[cfg(feature = "android")]
pub use build_android::AndroidBuilder;

mod simple_ui_page;
use simple_ui_page::SimpleUiPage;

mod manifest_processor;

/// Supported web frameworks
#[non_exhaustive]
#[derive(Copy, Clone, Debug)]
pub enum Framework {
	/// [Rocket](https://crates.io/crates/rocket)
	///
	/// [WasmBuilder] will generate `mount_to` function which may be used to mount
	/// all generated pages to [rocket::Rocket]
	/// ```
	/// mod generated {
	///     // There will be a function
	///     // pub fn mount_to(rocket: rocket::Rocket) -> rocket::Rocket
	///     include!(concat!(env!("OUT_DIR"), "/uni_build_generated.rs"));
	/// }
	///
	/// fn main() {
	///     let ignite = rocket::ignite();
	///     let ignite = generated::mount_to(ignite);
	///     ignite.launch();
	/// }
	/// ```
	Rocket,

	/// [Tide](https://docs.rs/tide/0.13.0/tide/)
	///
	/// [WasmBuilder] will generate `attach` function which may be used to attach
	/// all generated pages to [tide::Server]
	///
	/// ```
	/// mod generated {
	///     // There will be a function
	///     // pub fn attach<T>(app: &mut tide::Server<T>)
	///     // where T : 'static + Send + Sync + Clone
	///     include!(concat!(env!("OUT_DIR"), "/uni_build_generated.rs"));
	/// }
	///
	/// fn main() -> Result<(), std::io::Error> {
	///
	///     return async_std::task::block_on(async {
	///         // create regular tide::Server
	///         let mut app = tide::new();
	///
	///         // Attach all generated pages to the tide::Server
	///         generated::attach(&mut app);
	///
	///         // Start tide::Server
	///         app.listen("localhost:8080").await?;
	///
	///         Ok(())
	///     });
	/// }
	/// ```
	Tide,
}

/// Builds ui-crates into WASM modules.
#[derive(Clone)]
pub struct WasmBuilder {
	framework: Framework,
	theme: String,
	pages: Vec<SimpleUiPage>,
	target_dir: Option<String>,
	manifest_processor: crate::manifest_processor::ManifestProcessor,
}

impl WasmBuilder {
	/// Creates new builder for Framework
	pub fn for_framework(framework: Framework) -> Self {
		return Self {
			framework,
			theme: String::new(),
			pages: Vec::new(),
			target_dir: None,
			manifest_processor: crate::manifest_processor::ManifestProcessor::new(),
		};
	}

	/// Specify path to the page and module_name which implements the page
	///
	/// * The path should be in format "/a/b/"
	/// * The crate_name should be the same as the crate name in
	/// [build-dependencies] secion of Cargo.toml
	pub fn add_path(
		&mut self,
		path: &str,
		crate_name: &str,
	) {
		let manifest_path =
			self.manifest_processor.get_manifest_path(crate_name).expect(&format!(
				"Crate:{} not found in manifest:{}. Please add the crate into \
				 [build-dependencies] list",
				crate_name,
				self.manifest_processor.manifest_path(),
			));

		self.pages.push(SimpleUiPage::new(
			path.to_owned(),
			crate_name.to_owned(),
			manifest_path,
		));
	}

	/// Specify UiPage and module_name which implements the page
	///
	/// The crate_name should be the same as the crate name in
	/// [build-dependencies] secion of Cargo.toml
	pub fn add_page<T>(
		&mut self,
		page: &'static dyn UiPage<Data = T>,
		crate_name: &str,
	) {
		self.add_path(page.path(), crate_name);
	}

	/// Setup css theme for the app.
	///
	/// We recommend to check `uniui_theme` crate for that
	pub fn default_css_theme(
		&mut self,
		theme: String,
	) {
		self.theme = theme;
	}

	/// Builds all added crates.
	///
	/// You can access the results via
	/// ```
	/// mod generated {
	///     include!(concat!(env!("OUT_DIR"), "/uni_build_generated.rs"));
	/// }
	/// ```
	///
	/// Please refer to particular [Framework]'s documentation for more information
	/// how it may be used.
	pub fn execute(self) {
		let dir = match self.target_dir.as_ref() {
			Some(dir) => dir.to_owned(),
			None => {
				match std::env::var("OUT_DIR") {
					Ok(dir) => dir,
					Err(_) => {
						let out_var_str = std::env::var("OUT_DIR")
							.expect("there is nothing in OUT_DIR");
						let mut target_path = std::path::Path::new(&out_var_str)
							.parent()
							.and_then(|p| p.parent())
							.and_then(|p| p.parent())
							.and_then(|p| p.parent())
							.and_then(|p| p.parent())
							.expect("unwind path to target failed")
							.to_path_buf();

						target_path.push("target_wasm");

						let dir = target_path.to_str().expect(
							"due to Rust's std::env::set_var limitations we have to \
							 convert path to string but it failed",
						);
						dir.to_owned()
					},
				}
			},
		};

		build_wasm::build_all_inner(&self.pages, self.framework, dir, &self.theme);
	}
}