openzeppelin_relayer/config/config_file/
plugin.rs

1use std::collections::HashSet;
2
3use crate::config::ConfigFileError;
4use serde::{Deserialize, Serialize};
5
6// TODO: in case we want to support other languages and add
7// more flexibility to the plugins folder, we should
8// move this to a config file
9const PLUGIN_FILE_TYPE: &str = ".ts";
10const PLUGIN_LANG: &str = "typescript";
11
12#[derive(Debug, Serialize, Deserialize, Clone)]
13pub struct PluginFileConfig {
14    pub id: String,
15    pub path: String,
16}
17
18pub struct PluginsFileConfig {
19    pub plugins: Vec<PluginFileConfig>,
20}
21
22impl PluginsFileConfig {
23    pub fn new(plugins: Vec<PluginFileConfig>) -> Self {
24        Self { plugins }
25    }
26
27    pub fn validate(&self) -> Result<(), ConfigFileError> {
28        let mut ids = HashSet::new();
29        for plugin in &self.plugins {
30            if !ids.insert(plugin.id.clone()) {
31                return Err(ConfigFileError::DuplicateId(plugin.id.clone()));
32            }
33
34            if plugin.id.is_empty() {
35                return Err(ConfigFileError::MissingField("id".into()));
36            }
37
38            if plugin.path.is_empty() {
39                return Err(ConfigFileError::MissingField("path".into()));
40            }
41
42            if !plugin.path.ends_with(PLUGIN_FILE_TYPE) {
43                return Err(ConfigFileError::InvalidFormat(format!(
44                    "Plugin path must be a {} file (ends with '{}')",
45                    PLUGIN_LANG, PLUGIN_FILE_TYPE
46                )));
47            }
48        }
49
50        Ok(())
51    }
52}