Skip to content

Commit

Permalink
feat: Add config::load
Browse files Browse the repository at this point in the history
  • Loading branch information
luis-herasme committed Jul 23, 2024
1 parent 0c60adf commit 3f64a3b
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 13 deletions.
70 changes: 69 additions & 1 deletion ghost-crab-common/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use dotenvy::dotenv;
use serde::Deserialize;
use std::collections::HashMap;
use serde_json::Error as SerdeError;
use std::path::PathBuf;
use std::{collections::HashMap, io::Error as IoError};
use std::{env, fs};

#[derive(Clone, Copy, Deserialize, Debug)]
#[serde(rename_all = "lowercase")]
Expand Down Expand Up @@ -43,3 +47,67 @@ pub struct Config {
pub networks: HashMap<String, String>,
pub block_handlers: HashMap<String, BlockHandler>,
}

#[derive(Debug)]
pub enum ConfigError {
FileNotFound(IoError),
CurrentDirNotFound(IoError),
InvalidConfig(SerdeError),
EnvVarNotFound(String),
}

impl std::fmt::Display for ConfigError {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
ConfigError::FileNotFound(error) => {
write!(formatter, "Config file not found: {}", error)
}
ConfigError::CurrentDirNotFound(error) => {
write!(formatter, "Current directory not found: {}", error)
}
ConfigError::InvalidConfig(error) => {
write!(formatter, "Invalid config format: {}", error)
}
ConfigError::EnvVarNotFound(var) => {
write!(formatter, "Environment variable not found: {}", var)
}
}
}
}

impl std::error::Error for ConfigError {}

pub fn load() -> Result<Config, ConfigError> {
dotenv().ok();

let config_path = get_config_path()?;
let config_string = read_config_file(&config_path)?;
let mut config: Config = parse_config(&config_string)?;
replace_env_vars(&mut config)?;

Ok(config)
}

fn get_config_path() -> Result<PathBuf, ConfigError> {
let current_dir = env::current_dir().map_err(|error| ConfigError::CurrentDirNotFound(error))?;
Ok(current_dir.join("config.json"))
}

fn read_config_file(path: &PathBuf) -> Result<String, ConfigError> {
fs::read_to_string(path).map_err(|error| ConfigError::FileNotFound(error))
}

fn parse_config(config_string: &str) -> Result<Config, ConfigError> {
serde_json::from_str(config_string).map_err(|error| ConfigError::InvalidConfig(error))
}

fn replace_env_vars(config: &mut Config) -> Result<(), ConfigError> {
for (_key, value) in &mut config.networks {
if value.starts_with('$') {
*value = env::var(&value[1..])
.map_err(|_| ConfigError::EnvVarNotFound(value[1..].to_string()))?;
}
}

Ok(())
}
15 changes: 3 additions & 12 deletions ghost-crab-macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
extern crate proc_macro;
use ghost_crab_common::config::{Config, ExecutionMode};
use ghost_crab_common::config::{self, ExecutionMode};
use proc_macro::TokenStream;
use proc_macro2::{Ident, Literal};
use quote::{format_ident, quote};
use std::fs;
use syn::{parse_macro_input, ItemFn};

#[proc_macro_attribute]
Expand All @@ -25,7 +24,7 @@ pub fn block_handler(metadata: TokenStream, input: TokenStream) -> TokenStream {
panic!("The source is missing");
}

let config = get_config();
let config = config::load().unwrap();
let source = config.block_handlers.get(name).expect("Source not found.");

let rpc_url = config.networks.get(&source.network).expect("RPC url not found for network");
Expand Down Expand Up @@ -83,14 +82,6 @@ pub fn block_handler(metadata: TokenStream, input: TokenStream) -> TokenStream {
})
}

fn get_config() -> Config {
let current_dir = std::env::current_dir().expect("Current directory not found");
let config_json_path = current_dir.join("config.json");
let content = fs::read_to_string(config_json_path).expect("Error reading config file");
let config: Config = serde_json::from_str(&content).expect("Error parsing config file");
return config;
}

fn get_source_and_event(metadata: TokenStream) -> (String, Ident) {
let metadata_string = metadata.to_string();
let mut metadata_split = metadata_string.split('.');
Expand Down Expand Up @@ -137,7 +128,7 @@ fn get_context_identifier(parsed: ItemFn) -> Ident {

fn create_handler(metadata: TokenStream, input: TokenStream, is_template: bool) -> TokenStream {
let (name, event_name) = get_source_and_event(metadata);
let config = get_config();
let config = config::load().unwrap();

let abi;
let network;
Expand Down

0 comments on commit 3f64a3b

Please sign in to comment.