forklaunch 1.33.0

Launch faster with forklaunch
//! Explicit native mapper selection. Storage authorization remains repository-owned.
use super::*;

pub(super) fn templates(
    dir: &Path,
    enabled: bool,
    mut files: Vec<RenderedTemplate>,
) -> Result<Vec<RenderedTemplate>> {
    let health = files
        .iter()
        .find(|file| file.path == dir.join("domain/services/health.rs"));
    let postgres = health.is_some_and(|file| file.content.contains("PostgresRepository"));
    let enabled = enabled && health.is_some();
    if !enabled {
        files.retain(|file| !file.path.starts_with(dir.join("domain/mappers")));
        for file in &mut files {
            if file.path == dir.join("domain/mod.rs") {
                file.content = file.content.replace("pub mod mappers;\n", "");
            }
        }
        return Ok(files);
    }
    for file in &mut files {
        let Ok(relative) = file.path.strip_prefix(dir) else {
            continue;
        };
        let relative = relative.to_string_lossy();
        match relative.as_ref() {
            "Cargo.toml" => {
                let mut cargo: toml_edit::DocumentMut = file.content.parse()?;
                let features = cargo["dependencies"]["forklaunch-core"]["features"].as_array_mut().context("core dependency features")?;
                if !features.iter().any(|value| value.as_str() == Some("mappers")) { features.push("mappers"); }
                file.content = cargo.to_string();
            }
            "domain/mappers/mod.rs" => file.content = "//! Explicit projections into validated public DTOs.\npub mod health;\npub use health::HealthMapper;\n".into(),
            "domain/services/health.rs" => {
                let repository = if postgres { "PostgresRepository" } else { "InMemoryRepository" };
                let count = if postgres { "self.repository.count().await?" } else { "self.repository.count()?" };
                file.content = format!("use crate::{{domain::{{schemas::HealthResponse, mappers::HealthMapper}}, persistence::{repository}, error::Result}};\n#[derive(Clone)]\npub struct HealthService {{ name: String, repository: {repository}, mapper: HealthMapper }}\nimpl HealthService {{\n    pub fn new(name: String, repository: {repository}) -> Result<Self> {{ Ok(Self {{ name, repository, mapper: HealthMapper::new()? }}) }}\n    pub async fn report(&self) -> Result<HealthResponse> {{\n        self.mapper.report(&self.name, {count}).await\n    }}\n}}\n");
            }
            "registrations.rs" => file.content = file.content.replace("HealthService::new(config.name.clone(), repository.clone())", "HealthService::new(config.name.clone(), repository.clone())?"),
            "api/controllers/health.rs" => file.content = file.content.replace("Ok(state.health.report())", "state.health.report().await.map_err(|_| EndpointError::Unavailable)"),
            "error.rs" => file.content = file.content.replace("    Storage(String),", "    Storage(String),\n    Mapping,").replace("            Self::Storage(message)", "            Self::Mapping => write!(formatter, \"invalid mapped response\"),\n            Self::Storage(message)"),
            _ => {}
        }
    }
    files.push(RenderedTemplate {
        path: dir.join("domain/mappers/health.rs"),
        content: render_static_rust_template(
            "rust/project/native-service/domain/mappers/health.rs",
        ),
        context: None,
    });
    Ok(files)
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn mapper_selection_wires_real_projection_for_memory_and_postgres() {
        let root = tempfile::tempdir().unwrap();
        let dir = root.path().join("src/notes");
        for postgres in [false, true] {
            let base = native_layout::service_templates(&dir, "notes", "Notes");
            let base = if postgres {
                service_database::templates(&dir, "notes", base).unwrap()
            } else {
                base
            };
            let mapped = templates(&dir, true, base.clone()).unwrap();
            let source = |path: &str| {
                mapped
                    .iter()
                    .find(|file| file.path == dir.join(path))
                    .unwrap()
                    .content
                    .as_str()
            };
            assert!(source("domain/mappers/health.rs").contains("CheckedMapper"));
            assert!(source("domain/services/health.rs").contains("self.mapper.report"));
            assert!(source("registrations.rs").contains("repository.clone())?"));
            assert!(source("api/controllers/health.rs").contains("state.health.report().await"));
            if postgres {
                assert!(source("Cargo.toml").contains("0.9"));
            }
            let plain = templates(&dir, false, base).unwrap();
            assert!(
                !plain
                    .iter()
                    .any(|file| file.path.starts_with(dir.join("domain/mappers")))
            );
            assert!(
                !plain
                    .iter()
                    .find(|file| file.path == dir.join("domain/mod.rs"))
                    .unwrap()
                    .content
                    .contains("mod mappers")
            );
        }
    }
}