Skip to main content

alef_core/config/resolved/
mod.rs

1//! `ResolvedCrateConfig` — the per-crate view that backends consume.
2//!
3//! Every backend in `alef-backend-*`, every codegen pass, scaffold step,
4//! e2e generator, and publish step takes a `&ResolvedCrateConfig`. The
5//! resolved view is what you get after merging a [`crate::config::raw_crate::RawCrateConfig`]
6//! with the workspace [`crate::config::workspace::WorkspaceConfig`] defaults.
7//!
8//! Resolution merges values *into* a per-crate value. Workspace defaults
9//! that the crate did not override are folded in. Output paths are
10//! resolved through the workspace [`crate::config::output::OutputTemplate`]
11//! unless the crate set an explicit path in its `[crates.output]` table.
12
13pub mod ffi;
14pub mod fields;
15pub mod identifiers;
16pub mod imports;
17pub mod lookups;
18pub mod naming;
19
20use serde::{Deserialize, Serialize};
21use std::collections::HashMap;
22use std::path::PathBuf;
23
24use crate::config::SourceCrate;
25use crate::config::dto::DtoConfig;
26use crate::config::e2e::E2eConfig;
27use crate::config::extras::{AdapterConfig, Language};
28use crate::config::languages::{
29    CSharpConfig, CustomModulesConfig, CustomRegistrationsConfig, DartConfig, ElixirConfig, FfiConfig, GleamConfig,
30    GoConfig, JavaConfig, JniConfig, KotlinAndroidConfig, KotlinConfig, NodeConfig, PhpConfig, PythonConfig, RConfig,
31    RubyConfig, SwiftConfig, WasmConfig, ZigConfig,
32};
33use crate::config::output::{
34    BuildCommandConfig, CitationConfig, CleanConfig, ExcludeConfig, IncludeConfig, LintConfig, OutputConfig,
35    ReadmeConfig, ScaffoldConfig, SetupConfig, SyncConfig, TestConfig, UpdateConfig,
36};
37use crate::config::publish::PublishConfig;
38use crate::config::tools::ToolsConfig;
39use crate::config::trait_bridge::TraitBridgeConfig;
40use crate::config::workspace::ClientConstructorConfig;
41use crate::config::{FormatConfig, GenerateConfig};
42
43/// Fully-resolved configuration for one crate.
44///
45/// Backends consume `&ResolvedCrateConfig`; they should not need to look at
46/// the workspace defaults directly. Anything a backend reads has already been
47/// merged in by [`crate::config::NewAlefConfig::resolve`].
48///
49/// `output_paths` is precomputed: for every language this crate targets, the
50/// map holds the resolved output directory (with `{crate}` and `{lang}`
51/// placeholders substituted).
52#[derive(Debug, Clone, Serialize, Deserialize)]
53pub struct ResolvedCrateConfig {
54    // -----------------------------------------------------------------
55    // Identity
56    // -----------------------------------------------------------------
57    pub name: String,
58    pub sources: Vec<PathBuf>,
59    pub source_crates: Vec<SourceCrate>,
60    pub version_from: String,
61    pub core_import: Option<String>,
62    pub workspace_root: Option<PathBuf>,
63    pub skip_core_import: bool,
64    pub error_type: Option<String>,
65    pub error_constructor: Option<String>,
66    pub features: Vec<String>,
67    pub path_mappings: HashMap<String, String>,
68    pub extra_dependencies: HashMap<String, toml::Value>,
69    pub auto_path_mappings: bool,
70
71    // -----------------------------------------------------------------
72    // Languages targeted by this crate
73    // -----------------------------------------------------------------
74    pub languages: Vec<Language>,
75
76    // -----------------------------------------------------------------
77    // Per-language settings (workspace defaults already merged)
78    // -----------------------------------------------------------------
79    pub python: Option<PythonConfig>,
80    pub node: Option<NodeConfig>,
81    pub ruby: Option<RubyConfig>,
82    pub php: Option<PhpConfig>,
83    pub elixir: Option<ElixirConfig>,
84    pub wasm: Option<WasmConfig>,
85    pub ffi: Option<FfiConfig>,
86    pub go: Option<GoConfig>,
87    pub java: Option<JavaConfig>,
88    pub dart: Option<DartConfig>,
89    pub kotlin: Option<KotlinConfig>,
90    pub kotlin_android: Option<KotlinAndroidConfig>,
91    pub jni: Option<JniConfig>,
92    pub swift: Option<SwiftConfig>,
93    pub gleam: Option<GleamConfig>,
94    pub csharp: Option<CSharpConfig>,
95    pub r: Option<RConfig>,
96    pub zig: Option<ZigConfig>,
97
98    // -----------------------------------------------------------------
99    // Filters
100    // -----------------------------------------------------------------
101    pub exclude: ExcludeConfig,
102    pub include: IncludeConfig,
103
104    /// Resolved output directory per language code (`"python"` → `packages/python/spikard/`).
105    /// Only contains entries for languages this crate actually targets.
106    pub output_paths: HashMap<String, PathBuf>,
107
108    /// Raw user-supplied per-language output paths from `[crates.output]`.
109    ///
110    /// Distinct from [`Self::output_paths`]: this preserves the original (possibly
111    /// `None`) value so methods that need to distinguish "user explicitly set this
112    /// path" from "template-derived" can do so. Used by [`Self::ffi_lib_name`] and
113    /// any other consumer that derives identifiers from the user-supplied path.
114    pub explicit_output: OutputConfig,
115
116    // -----------------------------------------------------------------
117    // Pipelines (workspace defaults merged with per-crate overrides)
118    // -----------------------------------------------------------------
119    pub lint: HashMap<String, LintConfig>,
120    pub test: HashMap<String, TestConfig>,
121    pub setup: HashMap<String, SetupConfig>,
122    pub update: HashMap<String, UpdateConfig>,
123    pub clean: HashMap<String, CleanConfig>,
124    pub build_commands: HashMap<String, BuildCommandConfig>,
125
126    // -----------------------------------------------------------------
127    // Generation flags
128    // -----------------------------------------------------------------
129    pub generate: GenerateConfig,
130    pub generate_overrides: HashMap<String, GenerateConfig>,
131    pub format: FormatConfig,
132    pub format_overrides: HashMap<String, FormatConfig>,
133    pub dto: DtoConfig,
134
135    // -----------------------------------------------------------------
136    // Workspace concerns surfaced to the crate (read-only inheritance)
137    // -----------------------------------------------------------------
138    pub tools: ToolsConfig,
139    pub opaque_types: HashMap<String, String>,
140    pub client_constructors: HashMap<String, ClientConstructorConfig>,
141    pub sync: Option<SyncConfig>,
142    pub citation: Option<CitationConfig>,
143
144    // -----------------------------------------------------------------
145    // Packaging, e2e, extensibility
146    // -----------------------------------------------------------------
147    pub publish: Option<PublishConfig>,
148    pub e2e: Option<E2eConfig>,
149    pub adapters: Vec<AdapterConfig>,
150    pub trait_bridges: Vec<TraitBridgeConfig>,
151    pub scaffold: Option<ScaffoldConfig>,
152    pub readme: Option<ReadmeConfig>,
153    pub custom_files: HashMap<String, Vec<PathBuf>>,
154    pub custom_modules: CustomModulesConfig,
155    pub custom_registrations: CustomRegistrationsConfig,
156}
157
158impl ResolvedCrateConfig {
159    /// Convenience accessor: the resolved output directory for a language.
160    /// Returns `None` if this crate does not target the language.
161    pub fn output_for(&self, lang: &str) -> Option<&std::path::Path> {
162        self.output_paths.get(lang).map(|p| p.as_path())
163    }
164
165    /// Whether this crate targets the given language.
166    pub fn targets(&self, lang: Language) -> bool {
167        self.languages.contains(&lang)
168    }
169}