proto_core/settings/
plugins.rs

1use super::{PluginType, merge_iter};
2use crate::config::PROTO_PLUGIN_KEY;
3use crate::id::Id;
4use schematic::{Config, ValidateError, ValidateResult};
5use serde::Serialize;
6use std::collections::BTreeMap;
7use warpgate::PluginLocator;
8
9fn validate_reserved_words<T>(
10    value: &BTreeMap<Id, PluginLocator>,
11    _partial: &T,
12    _context: &(),
13    _finalize: bool,
14) -> ValidateResult {
15    if value.contains_key(PROTO_PLUGIN_KEY) {
16        return Err(ValidateError::new(
17            "proto is a reserved keyword, cannot use as a plugin identifier",
18        ));
19    }
20
21    Ok(())
22}
23
24#[derive(Clone, Config, Debug, Serialize)]
25#[config(allow_unknown_fields)]
26#[serde(rename_all = "kebab-case")]
27pub struct ProtoPluginsConfig {
28    #[serde(skip_serializing_if = "BTreeMap::is_empty")]
29    #[setting(merge = merge_iter, validate = validate_reserved_words)]
30    pub backends: BTreeMap<Id, PluginLocator>,
31
32    #[serde(skip_serializing_if = "BTreeMap::is_empty")]
33    #[setting(merge = merge_iter, validate = validate_reserved_words)]
34    pub tools: BTreeMap<Id, PluginLocator>,
35
36    // This is unfortunately required for flattening!
37    #[serde(flatten, skip_serializing_if = "BTreeMap::is_empty")]
38    #[setting(merge = merge_iter, validate = validate_reserved_words)]
39    pub legacy: BTreeMap<Id, PluginLocator>,
40}
41
42impl ProtoPluginsConfig {
43    pub fn get(&self, id: &Id, ty: PluginType) -> Option<&PluginLocator> {
44        if ty == PluginType::Backend {
45            self.backends.get(id)
46        } else {
47            self.tools.get(id).or_else(|| self.legacy.get(id))
48        }
49    }
50}