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}