use std::fs;
use crate::config::{SimiConfig, SimiStage};
use crate::error::*;
use crate::external_cmds as cmds;
pub fn create_simi_app(config: &SimiConfig) -> Result<(), Error> {
create_style_css_from_scss(config)?;
create_simi_app_index_html(config)?;
copy_modified_statics_to_output(config)?;
Ok(())
}
fn create_simi_app_index_html(config: &SimiConfig) -> Result<(), Error> {
if let Some(index_path) = config.get_index_html_path(SimiStage::UserSource) {
cmds::copy(
&index_path.to_string_lossy(),
&config.output_path().to_string_lossy(),
)?;
} else {
println!("Generate default index.html");
fs::write(
config
.get_index_html_path(SimiStage::SimiFinalApp)
.expect("Path for SimiFinalApp must be exists"),
default_index_html(config),
)?;
}
Ok(())
}
fn create_style_css_from_scss(config: &SimiConfig) -> Result<(), Error> {
use rsass::{compile_scss_file, OutputStyle};
if let Some(scss) = config.get_scss_path() {
println!(
"Generate css from scss: {}",
scss.file_name()
.expect("There must be a filename")
.to_string_lossy()
);
let css = match compile_scss_file(scss, OutputStyle::Compressed) {
Ok(rs) => rs,
Err(e) => {
return Err(format_err!("error compiling scss: {}", e));
}
};
fs::write(config.get_css_path(), css)?;
}
Ok(())
}
fn copy_modified_statics_to_output(config: &SimiConfig) -> Result<(), Error> {
let static_source = config.get_static_path();
if !static_source.exists() {
return Ok(());
}
let output_path = config.output_path();
let scss = config.get_scss_path();
let index = config.get_index_html_path(SimiStage::UserSource);
for entry in ::walkdir::WalkDir::new(&static_source) {
match entry {
Err(e) => println!("Ignore error {}", e),
Ok(entry) => {
let path = entry.path();
if let Some(scss) = scss {
if scss == path {
continue;
}
}
if let Some(ref index) = index {
if index == path {
continue;
}
}
let rel_path = path
.strip_prefix(&static_source)
.expect("Strip prefix for static content must be ok");
let output_path = output_path.join(rel_path);
if path.is_dir() {
fs::create_dir_all(&output_path)?;
} else {
cmds::copy(&path.to_string_lossy(), &output_path.to_string_lossy())?;
}
}
}
}
Ok(())
}
fn default_index_html(config: &SimiConfig) -> String {
let link_css = config.get_css_file_name().map_or("".to_string(), |css| {
format!("<link rel='stylesheet' href='./{}'>", css)
});
let (js_path, wasm_path_to_fetch) = if let Some(path) = config.wasm_serve_path() {
(
format!("{}/{}.js", path, config.simi_app_name()),
format!("{}/{}", path, config.get_wasm_file_name(true)),
)
} else {
(
format!("./{}.js", config.simi_app_name()),
config.get_wasm_file_name(true),
)
};
format!(
"\
<html>
<head>
<meta content=\"text/html;charset=utf-8\" http-equiv=\"Content-Type\"/>
{}
</head>
<body>
<p>Your page is loading...! Please wait for a moment!</p>
<p>If your page does not load correctly after a few moment, there must be some errors in your app. Did you add <b>#[simi_app]</b> to your struct?</p>
<script type='module'>
import {{ AppHandle, default as init }} from '{}'
async function run() {{
await init('{}');
window.simi_app = new AppHandle();
}}
run();
</script>
</body>
</html>",
link_css,
js_path,
wasm_path_to_fetch,
)
}