use std::{env, fs, path::PathBuf};
use midenc_frontend_wasm_metadata::{FrontendMetadata, WASM_FRONTEND_METADATA_CUSTOM_SECTION_NAME};
use proc_macro2::{Literal, Span, TokenStream as TokenStream2};
use quote::{format_ident, quote};
use syn::Error;
const BUNDLED_WIT_DEPS_DIR: &str = "bundled-miden-wit";
const GENERATED_WIT_DIR: &str = "generated-wit";
const FRONTEND_METADATA_BYTES_STATIC_IDENT: &str = "__miden_frontend_metadata_bytes";
pub(crate) const FRONTEND_METADATA_UNIQUENESS_GUARD_SYMBOL: &str =
"__MIDEN_FRONTEND_METADATA_UNIQUENESS_GUARD";
fn target_folder() -> PathBuf {
let mut manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR is not set");
manifest_dir.push_str("/target/");
PathBuf::from(manifest_dir)
}
pub fn bundled_wit_folder() -> Result<PathBuf, Error> {
let out_dir = target_folder();
let wit_deps_dir = out_dir.join(BUNDLED_WIT_DEPS_DIR);
fs::create_dir_all(&wit_deps_dir).map_err(|err| {
Error::new(
Span::call_site(),
format!(
"failed to create WIT dependencies directory '{}': {err}",
wit_deps_dir.display()
),
)
})?;
Ok(wit_deps_dir)
}
pub fn generated_wit_folder() -> Result<PathBuf, Error> {
let out_dir = target_folder();
let wit_deps_dir = out_dir.join(GENERATED_WIT_DIR);
fs::create_dir_all(&wit_deps_dir).map_err(|err| {
Error::new(
Span::call_site(),
format!(
"failed to create WIT dependencies directory '{}': {err}",
wit_deps_dir.display()
),
)
})?;
Ok(wit_deps_dir)
}
pub(crate) fn generate_frontend_link_section(metadata: &FrontendMetadata) -> TokenStream2 {
let metadata_bytes = metadata.to_bytes().unwrap_or_else(|err| panic!("{err}"));
let metadata_len = metadata_bytes.len();
let encoded_bytes = Literal::byte_string(&metadata_bytes);
let metadata_static_ident = format_ident!("{}", FRONTEND_METADATA_BYTES_STATIC_IDENT);
quote! {
const _: () = {
#[doc(hidden)]
#[used]
#[unsafe(export_name = #FRONTEND_METADATA_UNIQUENESS_GUARD_SYMBOL)]
static __miden_frontend_metadata_uniqueness_guard: u8 = 0;
};
#[unsafe(
// Keep the Mach-O-friendly `segment,section` naming scheme used by the main metadata
// section so the linker preserves these bytes in test and release builds.
link_section = #WASM_FRONTEND_METADATA_CUSTOM_SECTION_NAME
)]
#[doc(hidden)]
#[allow(clippy::octal_escapes)]
pub static #metadata_static_ident: [u8; #metadata_len] = *#encoded_bytes;
}
}
pub fn strip_line_comment(line: &str) -> &str {
match line.split_once("//") {
Some((before, _)) => before,
None => line,
}
}