Skip to content

Commit

Permalink
Refactored and separated file format
Browse files Browse the repository at this point in the history
  • Loading branch information
mdmmn378 committed Feb 8, 2024
1 parent 30cdab6 commit e2f5ec1
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 44 deletions.
5 changes: 5 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
HELLO=string
TAYLOR=string
AGE=int
SCORE=float
ACTIVE=bool
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

clap = { version = "4.4.14", features = ["derive"] }
colored = "2.1.0"
indexmap = "2.1.0"
anyhow = "1.0.79"
12 changes: 12 additions & 0 deletions lefthook.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
pre-commit:
commands:
format:
glob: "*.rs"
run: cargo fmt

check:
run: "cargo check"

test:
run: "cargo test"

27 changes: 27 additions & 0 deletions src/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#[derive(Debug, PartialEq)]
pub enum SupportedFormats {
ENV,
TOML,
YAML,
INVALID,
}

impl SupportedFormats {
pub fn to_string(&self) -> String {
match self {
SupportedFormats::ENV => "env",
SupportedFormats::TOML => "toml",
SupportedFormats::YAML => "yaml",
_ => "invalid",
}
.to_string()
}

pub fn supported_formats() -> Vec<String> {
return vec![
SupportedFormats::ENV.to_string(),
SupportedFormats::TOML.to_string(),
SupportedFormats::YAML.to_string(),
];
}
}
63 changes: 22 additions & 41 deletions src/io_manager.rs → src/dotenv_handler.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,13 @@
use colored::*;
use indexmap::IndexMap;
use std::fs::File;
use std::io::prelude::*;
use std::io::{BufRead, BufReader, Error};

static SUPPORTED_FORMATS: [&str; 1] = ["env"];
use anyhow::Result;

#[allow(dead_code)]
fn read_dot_env(path: &str) -> Result<IndexMap<String, String>, Error> {
fn read_dotenv(path: &str) -> Result<IndexMap<String, String>, Error> {
let mut env = IndexMap::new();
if std::path::Path::new(path).exists() == false {
println!("{} {}", "❌ Error:".red(), "File not found".bold());
std::process::exit(1);
}
let format = path.split('.').last().unwrap();
if SUPPORTED_FORMATS.contains(&format) == false {
println!(
"{} {}",
"❌ Error:".red(),
"Unsupported file format".bold()
);
println!(
"{} {}",
"Supported formats:".bold(),
SUPPORTED_FORMATS.join(", ").bold()
);
std::process::exit(1);
}
let file = File::open(path)?;
let reader = BufReader::new(file);
for line in reader.lines() {
Expand Down Expand Up @@ -65,17 +46,6 @@ fn get_type(value: &str) -> &str {
}
}

#[allow(dead_code)]
fn generate_dot_env_string(env: IndexMap<String, String>) -> String {
let mut env_string = String::new();
for (key, val) in env {
let val_type = get_type(&val);
env_string.push_str(&format!("{}={}\n", key, val_type));
}
env_string = env_string.strip_suffix("\n").unwrap().to_string();
env_string
}

fn remove_comments(text: &str) -> String {
let mut text = text.to_string();
// From: # This is a comment, To: ""
Expand All @@ -86,9 +56,20 @@ fn remove_comments(text: &str) -> String {
text
}

pub fn generate_dot_env_file(dry_run: bool, path: &str) -> Result<(), Error> {
let env = read_dot_env(path)?;
let mut env_string = generate_dot_env_string(env);
#[allow(dead_code)]
fn generate_dotenv_string(env: IndexMap<String, String>) -> Result<String> {
let mut env_string = String::new();
for (key, val) in env {
let val_type = get_type(&val);
env_string.push_str(&format!("{}={}\n", key, val_type));
}
env_string = env_string.strip_suffix("\n").unwrap().to_string();
Ok(env_string)
}

pub fn generate_dotenv_file(dry_run: bool, path: &str) -> Result<()> {
let env = read_dotenv(path)?;
let mut env_string = generate_dotenv_string(env)?;
env_string.push_str("\n");
let mut file = File::create(".env.example")?;
if dry_run {
Expand All @@ -105,7 +86,7 @@ mod tests {

#[test]
fn test_read_env() {
let env = read_dot_env("test.env").unwrap();
let env = read_dotenv("test.env").unwrap();
assert_eq!(env.get("HELLO").unwrap(), "ADELE");
assert_eq!(env.get("TAYLOR").unwrap(), "SWIFT");
}
Expand All @@ -123,11 +104,11 @@ mod tests {
}

#[test]
fn test_generate_dot_env_string() {
fn test_generate_dotenv_string() {
let mut env = IndexMap::new();
env.insert("HELLO".to_string(), "ADELE".to_string());
env.insert("WORLD".to_string(), "21".to_string());
let env_string = generate_dot_env_string(env);
let env_string = generate_dotenv_string(env).unwrap();
assert_eq!(env_string, "HELLO=string\nWORLD=int");
}

Expand All @@ -145,14 +126,14 @@ mod tests {
}

#[test]
fn test_generate_dot_env_file() {
generate_dot_env_file(false, "test.env").unwrap();
fn test_generate_dotenv_file() {
generate_dotenv_file(false, "test.env").unwrap();
let mut file = File::open(".env.example").unwrap();
let mut contents = String::new();
file.read_to_string(&mut contents).unwrap();
assert_eq!(
contents,
"HELLO=string\nTAYLOR=string\nAGE=int\nSCORE=float\nACTIVE=bool"
"HELLO=string\nTAYLOR=string\nAGE=int\nSCORE=float\nACTIVE=bool\n"
);
}
}
28 changes: 25 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,35 @@
mod io_manager;
mod common;
mod dotenv_handler;
mod utils;

use clap::{ArgAction, Command};
use colored::*;
use io_manager::generate_dot_env_file;
use common::SupportedFormats;
use dotenv_handler::generate_dotenv_file;
use utils::validate_file;

fn generate(val: &clap::ArgMatches) {
let path = val.get_one::<String>("path").unwrap();
let format = validate_file(&path);
let dry_run: bool = val.get_flag("dry-run");
generate_dot_env_file(dry_run, &path).unwrap();
match format {
SupportedFormats::ENV => {
let _ = generate_dotenv_file(dry_run, &path);
}
_ => {
println!(
"{} {}",
"❌ Error:".red(),
"Unsupported file format".bold()
);
println!(
"{} {}",
"Supported formats:".bold(),
SupportedFormats::supported_formats().join(", ").bold()
);
std::process::exit(1);
}
}
if !dry_run {
println!(
"{} {}",
Expand Down
42 changes: 42 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use crate::common::SupportedFormats;
use colored::*;

fn _extract_file_format(path: &str) -> SupportedFormats {
let file_extension = path.split('.').last().unwrap();
match file_extension {
"env" => SupportedFormats::ENV,
"toml" => SupportedFormats::TOML,
"yaml" => SupportedFormats::YAML,
_ => SupportedFormats::INVALID,
}
}

fn _check_file_format(path: &str) -> SupportedFormats {
let format = _extract_file_format(path);
if format == SupportedFormats::INVALID {
println!(
"{} {}",
"❌ Error:".red(),
"Unsupported file format".bold()
);
println!(
"{} {}",
"Supported formats:".bold(),
SupportedFormats::supported_formats().join(", ").bold()
);
std::process::exit(1);
}
return format;
}

fn _check_path_exists(path: &str) {
if std::path::Path::new(path).exists() == false {
println!("{} {}", "❌ Error:".red(), "File not found".bold());
std::process::exit(1);
}
}

pub fn validate_file(path: &str) -> SupportedFormats {
_check_path_exists(path);
_check_file_format(path)
}
2 changes: 2 additions & 0 deletions test.env
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ AGE=25
ACTIVE =true

#


0 comments on commit e2f5ec1

Please sign in to comment.