perf: make LeptosOptions lighter-weight to clone (closes #3036) (#3136)

This commit is contained in:
Greg Johnston
2024-10-20 20:05:29 -04:00
committed by GitHub
parent 70d06e2716
commit 98eccc9eb8
12 changed files with 60 additions and 56 deletions

View File

@@ -63,7 +63,7 @@ async fn main() -> std::io::Result<()> {
</html> </html>
} }
}}) }})
.service(Files::new("/", site_root)) .service(Files::new("/", site_root.as_ref()))
}) })
.bind(&addr)? .bind(&addr)?
.run() .run()

View File

@@ -56,7 +56,7 @@ async fn main() -> std::io::Result<()> {
</html> </html>
} }
}}) }})
.service(Files::new("/", site_root)) .service(Files::new("/", site_root.as_ref()))
//.wrap(middleware::Compress::default()) //.wrap(middleware::Compress::default())
}) })
.bind(&addr)? .bind(&addr)?

View File

@@ -39,7 +39,7 @@ async fn main() -> std::io::Result<()> {
</html> </html>
} }
}}) }})
.service(Files::new("/", site_root)) .service(Files::new("/", site_root.as_ref()))
//.wrap(middleware::Compress::default()) //.wrap(middleware::Compress::default())
}) })
.bind(&addr)? .bind(&addr)?

View File

@@ -41,7 +41,7 @@ async fn main() -> std::io::Result<()> {
</html> </html>
} }
}}) }})
.service(Files::new("/", site_root)) .service(Files::new("/", site_root.as_ref()))
}) })
.bind(addr)? .bind(addr)?
.workers(1) .workers(1)

View File

@@ -40,7 +40,7 @@ async fn main() -> std::io::Result<()> {
</html> </html>
} }
}}) }})
.service(Files::new("/", site_root)) .service(Files::new("/", site_root.as_ref()))
.wrap(middleware::Compress::default()) .wrap(middleware::Compress::default())
}) })
.bind(&addr)? .bind(&addr)?

View File

@@ -59,7 +59,7 @@ async fn main() -> std::io::Result<()> {
</html> </html>
} }
}}) }})
.service(Files::new("/", site_root)) .service(Files::new("/", site_root.as_ref()))
//.wrap(middleware::Compress::default()) //.wrap(middleware::Compress::default())
}) })
.bind(&addr)? .bind(&addr)?

View File

@@ -50,7 +50,7 @@ pub fn HydrationScripts(
path.parent().map(|p| p.to_path_buf()).unwrap_or_default() path.parent().map(|p| p.to_path_buf()).unwrap_or_default()
}) })
.unwrap_or_default() .unwrap_or_default()
.join(&options.hash_file); .join(options.hash_file.as_ref());
if hash_path.exists() { if hash_path.exists() {
let hashes = std::fs::read_to_string(&hash_path) let hashes = std::fs::read_to_string(&hash_path)
.expect("failed to read hash file"); .expect("failed to read hash file");

View File

@@ -15,7 +15,7 @@ config = { version = "0.14.0", default-features = false, features = [
"convert-case", "convert-case",
] } ] }
regex = "1.10" regex = "1.10"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive", "rc"] }
thiserror = "1.0" thiserror = "1.0"
typed-builder = "0.19.1" typed-builder = "0.19.1"

View File

@@ -5,7 +5,9 @@ pub mod errors;
use crate::errors::LeptosConfigError; use crate::errors::LeptosConfigError;
use config::{Case, Config, File, FileFormat}; use config::{Case, Config, File, FileFormat};
use regex::Regex; use regex::Regex;
use std::{env::VarError, fs, net::SocketAddr, path::Path, str::FromStr}; use std::{
env::VarError, fs, net::SocketAddr, path::Path, str::FromStr, sync::Arc,
};
use typed_builder::TypedBuilder; use typed_builder::TypedBuilder;
/// A Struct to allow us to parse LeptosOptions from the file. Not really needed, most interactions should /// A Struct to allow us to parse LeptosOptions from the file. Not really needed, most interactions should
@@ -25,17 +27,17 @@ pub struct ConfFile {
pub struct LeptosOptions { pub struct LeptosOptions {
/// The name of the WASM and JS files generated by wasm-bindgen. Defaults to the crate name with underscores instead of dashes /// The name of the WASM and JS files generated by wasm-bindgen. Defaults to the crate name with underscores instead of dashes
#[builder(setter(into), default=default_output_name())] #[builder(setter(into), default=default_output_name())]
pub output_name: String, pub output_name: Arc<str>,
/// The path of the all the files generated by cargo-leptos. This defaults to '.' for convenience when integrating with other /// The path of the all the files generated by cargo-leptos. This defaults to '.' for convenience when integrating with other
/// tools. /// tools.
#[builder(setter(into), default=default_site_root())] #[builder(setter(into), default=default_site_root())]
#[serde(default = "default_site_root")] #[serde(default = "default_site_root")]
pub site_root: String, pub site_root: Arc<str>,
/// The path of the WASM and JS files generated by wasm-bindgen from the root of your app /// The path of the WASM and JS files generated by wasm-bindgen from the root of your app
/// By default, wasm-bindgen puts them in `pkg`. /// By default, wasm-bindgen puts them in `pkg`.
#[builder(setter(into), default=default_site_pkg_dir())] #[builder(setter(into), default=default_site_pkg_dir())]
#[serde(default = "default_site_pkg_dir")] #[serde(default = "default_site_pkg_dir")]
pub site_pkg_dir: String, pub site_pkg_dir: Arc<str>,
/// Used to configure the running environment of Leptos. Can be used to load dev constants and keys v prod, or change /// Used to configure the running environment of Leptos. Can be used to load dev constants and keys v prod, or change
/// things based on the deployment environment /// things based on the deployment environment
/// I recommend passing in the result of `env::var("LEPTOS_ENV")` /// I recommend passing in the result of `env::var("LEPTOS_ENV")`
@@ -66,11 +68,11 @@ pub struct LeptosOptions {
/// The path of a custom 404 Not Found page to display when statically serving content, defaults to `site_root/404.html` /// The path of a custom 404 Not Found page to display when statically serving content, defaults to `site_root/404.html`
#[builder(default = default_not_found_path())] #[builder(default = default_not_found_path())]
#[serde(default = "default_not_found_path")] #[serde(default = "default_not_found_path")]
pub not_found_path: String, pub not_found_path: Arc<str>,
/// The file name of the hash text file generated by cargo-leptos. Defaults to `hash.txt`. /// The file name of the hash text file generated by cargo-leptos. Defaults to `hash.txt`.
#[builder(default = default_hash_file_name())] #[builder(default = default_hash_file_name())]
#[serde(default = "default_hash_file_name")] #[serde(default = "default_hash_file_name")]
pub hash_file: String, pub hash_file: Arc<str>,
/// If true, hashes will be generated for all files in the site_root and added to their file names. /// If true, hashes will be generated for all files in the site_root and added to their file names.
/// Defaults to `true`. /// Defaults to `true`.
#[builder(default = default_hash_files())] #[builder(default = default_hash_files())]
@@ -96,9 +98,9 @@ impl LeptosOptions {
); );
} }
Ok(LeptosOptions { Ok(LeptosOptions {
output_name, output_name: output_name.into(),
site_root: env_w_default("LEPTOS_SITE_ROOT", "target/site")?, site_root: env_w_default("LEPTOS_SITE_ROOT", "target/site")?.into(),
site_pkg_dir: env_w_default("LEPTOS_SITE_PKG_DIR", "pkg")?, site_pkg_dir: env_w_default("LEPTOS_SITE_PKG_DIR", "pkg")?.into(),
env: env_from_str(env_w_default("LEPTOS_ENV", "DEV")?.as_str())?, env: env_from_str(env_w_default("LEPTOS_ENV", "DEV")?.as_str())?,
site_addr: env_w_default("LEPTOS_SITE_ADDR", "127.0.0.1:3000")? site_addr: env_w_default("LEPTOS_SITE_ADDR", "127.0.0.1:3000")?
.parse()?, .parse()?,
@@ -113,8 +115,10 @@ impl LeptosOptions {
reload_ws_protocol: ws_from_str( reload_ws_protocol: ws_from_str(
env_w_default("LEPTOS_RELOAD_WS_PROTOCOL", "ws")?.as_str(), env_w_default("LEPTOS_RELOAD_WS_PROTOCOL", "ws")?.as_str(),
)?, )?,
not_found_path: env_w_default("LEPTOS_NOT_FOUND_PATH", "/404")?, not_found_path: env_w_default("LEPTOS_NOT_FOUND_PATH", "/404")?
hash_file: env_w_default("LEPTOS_HASH_FILE_NAME", "hash.txt")?, .into(),
hash_file: env_w_default("LEPTOS_HASH_FILE_NAME", "hash.txt")?
.into(),
hash_files: env_w_default("LEPTOS_HASH_FILES", "false")?.parse()?, hash_files: env_w_default("LEPTOS_HASH_FILES", "false")?.parse()?,
}) })
} }
@@ -126,16 +130,16 @@ impl Default for LeptosOptions {
} }
} }
fn default_output_name() -> String { fn default_output_name() -> Arc<str> {
env!("CARGO_CRATE_NAME").replace('-', "_") env!("CARGO_CRATE_NAME").replace('-', "_").into()
} }
fn default_site_root() -> String { fn default_site_root() -> Arc<str> {
".".to_string() ".".into()
} }
fn default_site_pkg_dir() -> String { fn default_site_pkg_dir() -> Arc<str> {
"pkg".to_string() "pkg".into()
} }
fn default_env() -> Env { fn default_env() -> Env {
@@ -150,12 +154,12 @@ fn default_reload_port() -> u32 {
3001 3001
} }
fn default_not_found_path() -> String { fn default_not_found_path() -> Arc<str> {
"/404".to_string() "/404".into()
} }
fn default_hash_file_name() -> String { fn default_hash_file_name() -> Arc<str> {
"hash.txt".to_string() "hash.txt".into()
} }
fn default_hash_files() -> bool { fn default_hash_files() -> bool {

View File

@@ -76,9 +76,9 @@ fn try_from_env_test() {
|| LeptosOptions::try_from_env().unwrap(), || LeptosOptions::try_from_env().unwrap(),
); );
assert_eq!(config.output_name, "app_test"); assert_eq!(config.output_name.as_ref(), "app_test");
assert_eq!(config.site_root, "my_target/site"); assert_eq!(config.site_root.as_ref(), "my_target/site");
assert_eq!(config.site_pkg_dir, "my_pkg"); assert_eq!(config.site_pkg_dir.as_ref(), "my_pkg");
assert_eq!( assert_eq!(
config.site_addr, config.site_addr,
SocketAddr::from_str("0.0.0.0:80").unwrap() SocketAddr::from_str("0.0.0.0:80").unwrap()

View File

@@ -50,9 +50,9 @@ async fn get_configuration_from_file_ok() {
) )
.await; .await;
assert_eq!(config.output_name, "app-test"); assert_eq!(config.output_name.as_ref(), "app-test");
assert_eq!(config.site_root, "my_target/site"); assert_eq!(config.site_root.as_ref(), "my_target/site");
assert_eq!(config.site_pkg_dir, "my_pkg"); assert_eq!(config.site_pkg_dir.as_ref(), "my_pkg");
assert_eq!( assert_eq!(
config.site_addr, config.site_addr,
SocketAddr::from_str("0.0.0.0:80").unwrap() SocketAddr::from_str("0.0.0.0:80").unwrap()
@@ -106,9 +106,9 @@ async fn get_config_from_file_ok() {
) )
.await; .await;
assert_eq!(config.output_name, "app-test"); assert_eq!(config.output_name.as_ref(), "app-test");
assert_eq!(config.site_root, "my_target/site"); assert_eq!(config.site_root.as_ref(), "my_target/site");
assert_eq!(config.site_pkg_dir, "my_pkg"); assert_eq!(config.site_pkg_dir.as_ref(), "my_pkg");
assert_eq!( assert_eq!(
config.site_addr, config.site_addr,
SocketAddr::from_str("0.0.0.0:80").unwrap() SocketAddr::from_str("0.0.0.0:80").unwrap()
@@ -151,9 +151,9 @@ fn get_config_from_str_content() {
|| get_config_from_str(CARGO_TOML_CONTENT_OK).unwrap(), || get_config_from_str(CARGO_TOML_CONTENT_OK).unwrap(),
); );
assert_eq!(config.output_name, "app-test"); assert_eq!(config.output_name.as_ref(), "app-test");
assert_eq!(config.site_root, "my_target/site"); assert_eq!(config.site_root.as_ref(), "my_target/site");
assert_eq!(config.site_pkg_dir, "my_pkg"); assert_eq!(config.site_pkg_dir.as_ref(), "my_pkg");
assert_eq!( assert_eq!(
config.site_addr, config.site_addr,
SocketAddr::from_str("0.0.0.0:80").unwrap() SocketAddr::from_str("0.0.0.0:80").unwrap()
@@ -178,9 +178,9 @@ async fn get_config_from_env() {
) )
.await; .await;
assert_eq!(config.output_name, "app-test"); assert_eq!(config.output_name.as_ref(), "app-test");
assert_eq!(config.site_root, "my_target/site"); assert_eq!(config.site_root.as_ref(), "my_target/site");
assert_eq!(config.site_pkg_dir, "my_pkg"); assert_eq!(config.site_pkg_dir.as_ref(), "my_pkg");
assert_eq!( assert_eq!(
config.site_addr, config.site_addr,
SocketAddr::from_str("0.0.0.0:80").unwrap() SocketAddr::from_str("0.0.0.0:80").unwrap()
@@ -202,8 +202,8 @@ async fn get_config_from_env() {
) )
.await; .await;
assert_eq!(config.site_root, "target/site"); assert_eq!(config.site_root.as_ref(), "target/site");
assert_eq!(config.site_pkg_dir, "pkg"); assert_eq!(config.site_pkg_dir.as_ref(), "pkg");
assert_eq!( assert_eq!(
config.site_addr, config.site_addr,
SocketAddr::from_str("127.0.0.1:3000").unwrap() SocketAddr::from_str("127.0.0.1:3000").unwrap()
@@ -215,10 +215,10 @@ async fn get_config_from_env() {
#[test] #[test]
fn leptos_options_builder_default() { fn leptos_options_builder_default() {
let conf = LeptosOptions::builder().output_name("app-test").build(); let conf = LeptosOptions::builder().output_name("app-test").build();
assert_eq!(conf.output_name, "app-test"); assert_eq!(conf.output_name.as_ref(), "app-test");
assert!(matches!(conf.env, Env::DEV)); assert!(matches!(conf.env, Env::DEV));
assert_eq!(conf.site_pkg_dir, "pkg"); assert_eq!(conf.site_pkg_dir.as_ref(), "pkg");
assert_eq!(conf.site_root, "."); assert_eq!(conf.site_root.as_ref(), ".");
assert_eq!( assert_eq!(
conf.site_addr, conf.site_addr,
SocketAddr::from_str("127.0.0.1:3000").unwrap() SocketAddr::from_str("127.0.0.1:3000").unwrap()
@@ -242,9 +242,9 @@ fn environment_variable_override() {
|| get_config_from_str(CARGO_TOML_CONTENT_OK).unwrap(), || get_config_from_str(CARGO_TOML_CONTENT_OK).unwrap(),
); );
assert_eq!(config.output_name, "app-test"); assert_eq!(config.output_name.as_ref(), "app-test");
assert_eq!(config.site_root, "my_target/site"); assert_eq!(config.site_root.as_ref(), "my_target/site");
assert_eq!(config.site_pkg_dir, "my_pkg"); assert_eq!(config.site_pkg_dir.as_ref(), "my_pkg");
assert_eq!( assert_eq!(
config.site_addr, config.site_addr,
SocketAddr::from_str("0.0.0.0:80").unwrap() SocketAddr::from_str("0.0.0.0:80").unwrap()
@@ -265,9 +265,9 @@ fn environment_variable_override() {
|| get_config_from_str(CARGO_TOML_CONTENT_OK).unwrap(), || get_config_from_str(CARGO_TOML_CONTENT_OK).unwrap(),
); );
assert_eq!(config.output_name, "app-test2"); assert_eq!(config.output_name.as_ref(), "app-test2");
assert_eq!(config.site_root, "my_target/site2"); assert_eq!(config.site_root.as_ref(), "my_target/site2");
assert_eq!(config.site_pkg_dir, "my_pkg2"); assert_eq!(config.site_pkg_dir.as_ref(), "my_pkg2");
assert_eq!( assert_eq!(
config.site_addr, config.site_addr,
SocketAddr::from_str("0.0.0.0:82").unwrap() SocketAddr::from_str("0.0.0.0:82").unwrap()

View File

@@ -54,7 +54,7 @@ pub fn HashedStylesheet(
path.parent().map(|p| p.to_path_buf()).unwrap_or_default() path.parent().map(|p| p.to_path_buf()).unwrap_or_default()
}) })
.unwrap_or_default() .unwrap_or_default()
.join(&options.hash_file); .join(options.hash_file.as_ref());
if hash_path.exists() { if hash_path.exists() {
let hashes = std::fs::read_to_string(&hash_path) let hashes = std::fs::read_to_string(&hash_path)
.expect("failed to read hash file"); .expect("failed to read hash file");