// SPDX-FileCopyrightText: 2025 Ruby Iris Juric // // SPDX-License-Identifier: 0BSD use std::{fs, process::Command}; use miette::{Context, IntoDiagnostic, Result, miette}; use crate::gleam_toml; enum Target { Erlang, Javascript, } impl Target { fn filename(&self) -> String { match self { Target::Erlang => "gleam_entrypoint.erl".to_string(), Target::Javascript => "gleam_entrypoint.mjs".to_string(), } } } impl TryFrom<&str> for Target { type Error = miette::Report; fn try_from(target: &str) -> Result { match target { "erlang" => Ok(Self::Erlang), "javascript" => Ok(Self::Javascript), _ => Err(miette!("Unknown target {target}")), } } } fn generate_module_source(module_name: &str, target: &Target) -> String { match target { Target::Erlang => format!( r#"-module('gleam_entrypoint'). -export([run/0]). run() -> {{ok, _}} = application:ensure_all_started('{module_name}'), {module_name}:main(), erlang:halt(0). "# ), Target::Javascript => format!( r#"import {{ main }} from "./{module_name}/{module_name}.mjs"; main(); "# ), } } pub fn generate_module(target: &str) -> Result<()> { let target: Target = target.try_into()?; let gleam_toml = gleam_toml::parse("gleam.toml")?; let source = generate_module_source(&gleam_toml.name, &target); fs::write(target.filename(), source) .into_diagnostic() .wrap_err("While writing entrypoint module source:")?; match target { Target::Javascript => Ok(()), Target::Erlang => { let compile_result = Command::new("erlc") .arg(target.filename()) .status() .into_diagnostic() .wrap_err("While running Erlang compiler:")?; if compile_result.success() { Ok(()) } else { Err(miette!("Entrypoint compilation failed")) } } } }