foundry_config/extend.rs
1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4
5/// Strategy for extending configuration from a base file.
6#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)]
7#[serde(rename_all = "kebab-case")]
8pub enum ExtendStrategy {
9 /// Uses `admerge` figment strategy.
10 /// Arrays are concatenated (base elements + local elements).
11 /// Other values are replaced (local values override base values).
12 #[default]
13 ExtendArrays,
14
15 /// Uses `merge` figment strategy.
16 /// Arrays are replaced entirely (local arrays replace base arrays).
17 /// Other values are replaced (local values override base values).
18 ReplaceArrays,
19
20 /// Throws an error if any of the keys in the inherited toml file are also in `foundry.toml`.
21 NoCollision,
22}
23
24/// Configuration for extending from a base file.
25///
26/// Supports two formats:
27/// - String: `extends = "base.toml"`
28/// - Object: `extends = { path = "base.toml", strategy = "no-collision" }`
29#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
30#[serde(untagged)]
31pub enum Extends {
32 /// Simple string path to base file
33 Path(String),
34 /// Detailed configuration with path and strategy
35 Config(ExtendConfig),
36}
37
38#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
39pub struct ExtendConfig {
40 pub path: String,
41 #[serde(default)]
42 pub strategy: Option<ExtendStrategy>,
43}
44
45impl Extends {
46 /// Get the path to the base file
47 pub fn path(&self) -> &str {
48 match self {
49 Self::Path(path) => path,
50 Self::Config(config) => &config.path,
51 }
52 }
53
54 /// Get the strategy to use for extending
55 pub fn strategy(&self) -> ExtendStrategy {
56 match self {
57 Self::Path(_) => ExtendStrategy::default(),
58 Self::Config(config) => config.strategy.unwrap_or_default(),
59 }
60 }
61}
62
63// -- HELPERS -----------------------------------------------------------------
64
65// Helper structs to only extract the 'extends' field and its strategy from the profiles
66#[derive(Deserialize, Default)]
67pub(crate) struct ExtendsPartialConfig {
68 #[serde(default)]
69 pub profile: Option<HashMap<String, ExtendsHelper>>,
70}
71
72#[derive(Deserialize, Default)]
73pub(crate) struct ExtendsHelper {
74 #[serde(default)]
75 pub extends: Option<Extends>,
76}