From 11eeae05d0d9bfdc3966d66df57b3a8e2fbb4797 Mon Sep 17 00:00:00 2001
From: Sebastien Rousseau <sebastienrousseau@users.noreply.github.com>
Date: Tue, 26 Mar 2024 12:14:29 +0000
Subject: [PATCH] refactor(libmake): :art: Refactor and decouple file
 generation logic

decoupled the generator functions into separate files
---
 examples/generate_from_args.rs |   2 +-
 examples/generate_from_csv.rs  |   4 +-
 examples/generate_from_json.rs |   2 +-
 examples/generate_from_toml.rs |   2 +-
 examples/generate_from_yaml.rs |   2 +-
 src/args.rs                    |  13 +-
 src/generator.rs               | 524 +--------------------------------
 src/generators/args.rs         |  81 +++++
 src/generators/csv.rs          |  65 ++++
 src/generators/ini.rs          |  45 +++
 src/generators/json.rs         |  47 +++
 src/generators/mod.rs          |  21 +-
 src/generators/toml.rs         |  45 +++
 src/generators/yaml.rs         |  45 +++
 src/interface.rs               |   3 +-
 src/macros/generator_macros.rs |  12 +-
 src/models/mod.rs              |   3 +
 src/models/model_params.rs     | 181 ++++++++++++
 src/parser.rs                  |  16 -
 src/utils.rs                   |  27 +-
 tests/test_args.rs             |   5 +-
 tests/test_generator.rs        |  11 +-
 tests/test_macros.rs           |   2 +-
 23 files changed, 598 insertions(+), 560 deletions(-)
 create mode 100644 src/generators/args.rs
 create mode 100644 src/generators/csv.rs
 create mode 100644 src/generators/ini.rs
 create mode 100644 src/generators/json.rs
 create mode 100644 src/generators/toml.rs
 create mode 100644 src/generators/yaml.rs
 create mode 100644 src/models/model_params.rs
 delete mode 100644 src/parser.rs

diff --git a/examples/generate_from_args.rs b/examples/generate_from_args.rs
index 89b491b..f42c328 100644
--- a/examples/generate_from_args.rs
+++ b/examples/generate_from_args.rs
@@ -28,7 +28,7 @@
 //! If there is an error, it will print an error message.
 
 // Import the necessary function for generating files from arguments
-use libmake::generator::generate_from_args;
+use libmake::generators::args::generate_from_args;
 
 /// A simple test program for the `generate_from_args` function.
 ///
diff --git a/examples/generate_from_csv.rs b/examples/generate_from_csv.rs
index 3a7bcf8..a58037f 100644
--- a/examples/generate_from_csv.rs
+++ b/examples/generate_from_csv.rs
@@ -31,7 +31,7 @@
 //! ```
 
 // Import the necessary function for generating templates from a CSV file.
-use libmake::generator::generate_from_csv;
+use libmake::generators::csv::generate_from_csv;
 
 /// Attempts to generate template files from the specified CSV file.
 ///
@@ -48,7 +48,7 @@ use libmake::generator::generate_from_csv;
 /// The following example demonstrates how to use the `generate_from_csv` function:
 ///
 /// ```rust
-/// use libmake::generator::generate_from_csv;
+/// use libmake::generators::csv::generate_from_csv;
 ///
 /// let csv_file_path = "./tests/data/mylibrary.csv";
 ///
diff --git a/examples/generate_from_json.rs b/examples/generate_from_json.rs
index b626724..676dffc 100644
--- a/examples/generate_from_json.rs
+++ b/examples/generate_from_json.rs
@@ -34,7 +34,7 @@
 //! ```
 
 // Import the necessary function for generating templates from a JSON file.
-use libmake::generator::generate_from_json;
+use libmake::generators::json::generate_from_json;
 
 /// Generate template files based on the data in the JSON file.
 ///
diff --git a/examples/generate_from_toml.rs b/examples/generate_from_toml.rs
index 4daa182..424b070 100644
--- a/examples/generate_from_toml.rs
+++ b/examples/generate_from_toml.rs
@@ -29,7 +29,7 @@
 //! ```
 //!
 // Import the necessary function for generating templates from a TOML file.
-use libmake::generator::generate_from_toml;
+use libmake::generators::toml::generate_from_toml;
 
 /// Generate template files based on the configuration in the TOML file.
 ///
diff --git a/examples/generate_from_yaml.rs b/examples/generate_from_yaml.rs
index ec77f7c..c37b205 100644
--- a/examples/generate_from_yaml.rs
+++ b/examples/generate_from_yaml.rs
@@ -30,7 +30,7 @@
 //! ```
 
 // Import the necessary function for generating templates from a YAML file.
-use libmake::generator::generate_from_yaml;
+use libmake::generators::yaml::generate_from_yaml;
 
 /// Generate template files from the specified YAML file.
 ///
diff --git a/src/args.rs b/src/args.rs
index e8cb07f..8484e06 100644
--- a/src/args.rs
+++ b/src/args.rs
@@ -4,12 +4,13 @@
 // Copyright © 2024 LibMake. All rights reserved.
 
 use super::{
-    extract_param,
-    generator::{
-        generate_files, generate_from_csv, generate_from_ini,
-        generate_from_json, generate_from_toml, generate_from_yaml,
-        FileGenerationParams,
-    },
+    extract_param, generator::generate_files,
+    generators::csv::generate_from_csv,
+    generators::ini::generate_from_ini,
+    generators::json::generate_from_json,
+    generators::toml::generate_from_toml,
+    generators::yaml::generate_from_yaml,
+    models::model_params::FileGenerationParams,
 };
 use clap::ArgMatches;
 use std::error::Error;
diff --git a/src/generator.rs b/src/generator.rs
index cffe85e..4546aab 100644
--- a/src/generator.rs
+++ b/src/generator.rs
@@ -3,214 +3,15 @@
 // SPDX-License-Identifier: Apache-2.0 OR MIT indicates dual licensing under Apache 2.0 or MIT licenses.
 // Copyright © 2024 LibMake. All rights reserved.
 
-use super::interface::replace_placeholders;
-use serde::{Deserialize, Serialize};
-use serde_ini::from_str;
-use std::{
-    fs, io,
-    path::{Path, PathBuf},
+use crate::{
+    interface::replace_placeholders, macro_generate_from_csv,
+    macro_generate_from_ini, macro_generate_from_json,
+    macro_generate_from_toml, macro_generate_from_yaml,
+    models::model_params::FileGenerationParams,
+    utils::create_directory,
 };
+use std::{fs, io, path::PathBuf};
 
-use crate::macro_generate_from_csv;
-use crate::macro_generate_from_ini;
-use crate::macro_generate_from_json;
-use crate::macro_generate_from_yaml;
-use crate::macro_generate_from_toml;
-use crate::macro_generate_files;
-
-/// Structure for holding the parameters for generating the project files.
-///
-/// # Description
-///
-/// * The `output` directory is the directory where the project files will be created.
-/// * The other parameters are optional and will be used to replace the placeholders in the template files.
-/// * The template files are located in the template directory of the project.
-/// * The template files are copied to the output directory and the placeholders are replaced with the values of the parameters.
-///
-#[derive(
-    Clone,
-    Debug,
-    Default,
-    Deserialize,
-    Eq,
-    Hash,
-    Ord,
-    PartialEq,
-    PartialOrd,
-    Serialize,
-)]
-pub struct FileGenerationParams {
-    /// The author of the project (optional).
-    pub author: Option<String>,
-    /// The build command to be used for building the project (optional).
-    pub build: Option<String>,
-    /// The categories that the project belongs to (optional).
-    pub categories: Option<String>,
-    /// A short description of the project (optional).
-    pub description: Option<String>,
-    /// The documentation URL of the project (optional).
-    pub documentation: Option<String>,
-    /// The edition of the project (optional).
-    pub edition: Option<String>,
-    /// The email address of the author (optional).
-    pub email: Option<String>,
-    /// The homepage of the project (optional).
-    pub homepage: Option<String>,
-    /// Keywords that describe the project (optional).
-    pub keywords: Option<String>,
-    /// The license under which the project is released (optional).
-    pub license: Option<String>,
-    /// The name of the project (optional).
-    pub name: Option<String>,
-    /// The output directory where the project files will be created (optional).
-    pub output: Option<String>,
-    /// The name of the readme file (optional).
-    pub readme: Option<String>,
-    /// The URL of the project's repository (optional).
-    pub repository: Option<String>,
-    /// The minimum Rust version required by the project (optional).
-    pub rustversion: Option<String>,
-    /// The initial version of the project (optional).
-    pub version: Option<String>,
-    /// The website of the project (optional).
-    pub website: Option<String>,
-}
-
-impl FileGenerationParams {
-    /// Creates a default instance with default values for all fields.
-    /// Fields that are truly optional without a default are initialized as `None`.
-    pub fn default_params() -> Self {
-        Self {
-            author: Some("John Smith".to_string()),
-            build: Some("build.rs".to_string()),
-            categories: Some(
-                "[\"category1\",\"category2\",\"category3\"]"
-                    .to_string(),
-            ),
-            description: Some(
-                "A Rust library for doing cool things".to_string(),
-            ),
-            documentation: Some(
-                "https://docs.rs/my_library".to_string(),
-            ),
-            edition: Some("2021".to_string()),
-            email: Some("john.smith@example.com".to_string()),
-            homepage: Some("https://my_library.rs".to_string()),
-            keywords: Some(
-                "[\"rust\",\"library\",\"cool\"]".to_string(),
-            ),
-            license: Some("MIT".to_string()),
-            name: Some("my_library".to_string()),
-            output: Some("my_library".to_string()),
-            readme: Some("README.md".to_string()),
-            repository: Some(
-                "https://github.com/example/my_library".to_string(),
-            ),
-            rustversion: Some("1.75.0".to_string()),
-            version: Some("0.1.0".to_string()),
-            website: Some("https://example.com/john-smith".to_string()),
-        }
-    }
-    /// Parses the command line arguments and returns a new instance of
-    /// the structure.
-
-    /// Creates a new instance with default values.
-    pub fn new() -> Self {
-        Self::default_params()
-    }
-    /// Parses the command line arguments and returns a new instance of
-    /// the structure.
-    ///
-    /// # Arguments
-    /// * `args_str` - A string slice containing the command line arguments.
-    ///
-    /// # Errors
-    /// Returns an `Err` if the arguments are not in the expected format
-    /// or if mandatory arguments are missing. The error is a `String`
-    /// describing what went wrong.
-    ///
-    pub fn from_args(args_str: &str) -> Result<Self, String> {
-        let mut params = Self::new();
-        let args: Vec<&str> = args_str.split_whitespace().collect();
-        for arg in args {
-            let mut arg_parts = arg.splitn(2, ' ');
-            let arg_name = arg_parts
-                .next()
-                .ok_or_else(|| "Missing argument name".to_string())?;
-            let arg_value = arg_parts
-                .next()
-                .ok_or_else(|| "Missing argument value".to_string())?;
-            match arg_name {
-                "--author" => {
-                    params.author = Some(arg_value.to_string());
-                }
-                "--build" => params.build = Some(arg_value.to_string()),
-                "--categories" => {
-                    params.categories = Some(arg_value.to_string());
-                }
-                "--description" => {
-                    params.description = Some(arg_value.to_string());
-                }
-                "--documentation" => {
-                    params.documentation = Some(arg_value.to_string());
-                }
-                "--edition" => {
-                    params.edition = Some(arg_value.to_string());
-                }
-                "--email" => params.email = Some(arg_value.to_string()),
-                "--homepage" => {
-                    params.homepage = Some(arg_value.to_string());
-                }
-                "--keywords" => {
-                    params.keywords = Some(arg_value.to_string());
-                }
-                "--license" => {
-                    params.license = Some(arg_value.to_string());
-                }
-                "--name" => params.name = Some(arg_value.to_string()),
-                "--output" => {
-                    params.output = Some(arg_value.to_string());
-                }
-                "--readme" => {
-                    params.readme = Some(arg_value.to_string());
-                }
-                "--repository" => {
-                    params.repository = Some(arg_value.to_string());
-                }
-                "--rustversion" => {
-                    params.rustversion = Some(arg_value.to_string());
-                }
-                "--version" => {
-                    params.version = Some(arg_value.to_string());
-                }
-                "--website" => {
-                    params.website = Some(arg_value.to_string());
-                }
-                _ => (),
-            }
-        }
-        Ok(params)
-    }
-}
-
-/// Creates a directory at the specified path.
-///
-/// # Arguments
-///
-/// * `path` - The path where the directory should be created.
-///
-/// # Errors
-///
-/// Returns an `io::Error` if the directory cannot be created. This could be due to
-/// various reasons such as insufficient permissions, the directory already existing,
-/// or other I/O-related errors.
-///
-pub fn create_directory(path: &Path) -> io::Result<()> {
-    fs::create_dir(path).or_else(|e| match e.kind() {
-        io::ErrorKind::AlreadyExists => Ok(()),
-        _ => Err(e),
-    })
-}
 /// Creates the template folder and downloads necessary template files.
 ///
 /// This function attempts to create a template directory in the current working directory
@@ -347,7 +148,8 @@ pub fn generate_files(params: FileGenerationParams) -> io::Result<()> {
 
     // Get the project directory path from the output parameter,
     // create a PathBuf from it, and assign it to the project_directory variable
-    let project_directory = PathBuf::from(output.clone().trim_matches('\"'));
+    let project_directory =
+        PathBuf::from(output.clone().trim_matches('\"'));
 
     // Creating the project directory
     create_directory(&project_directory)?;
@@ -469,7 +271,10 @@ pub fn generate_files(params: FileGenerationParams) -> io::Result<()> {
 /// - There are issues parsing the configuration file into the `FileGenerationParams` struct.
 /// - Any errors occur during the file generation process based on the configuration.
 ///
-pub fn generate_from_config(path: &str, file_type: &str) -> Result<(), String> {
+pub fn generate_from_config(
+    path: &str,
+    file_type: &str,
+) -> Result<(), String> {
     match file_type {
         "csv" => macro_generate_from_csv!(path)?,
         "ini" => macro_generate_from_ini!(path)?,
@@ -486,306 +291,3 @@ pub fn generate_from_config(path: &str, file_type: &str) -> Result<(), String> {
     Ok(())
 }
 
-/// Generates files for a new Rust project based on a CSV file.
-///
-/// # Arguments
-///
-/// The CSV file must contain the following columns:
-///
-/// - `author` - the author of the project (optional).
-/// - `build` - the build command to be used for building the project (optional).
-/// - `categories` - the categories that the project belongs to (optional).
-/// - `description` - a short description of the project (optional).
-/// - `documentation` - the documentation URL of the project (optional).
-/// - `edition` - the edition of the project (optional).
-/// - `email` - the email address of the author (optional).
-/// - `homepage` - the homepage of the project (optional).
-/// - `keywords` - keywords that describe the project (optional).
-/// - `license` - the license under which the project is released (optional).
-/// - `name` - the name of the project (optional).
-/// - `output` - the output directory where the project files will be created (required).
-/// - `readme` - the name of the readme file (optional).
-/// - `repository` - the url of the project's repository (optional).
-/// - `rustversion` - the minimum Rust version required by the project (optional).
-/// - `version` - the initial version of the project (optional).
-/// - `website` - the website of the project (optional).
-///
-/// # Errors
-///
-/// This function will return an error in the following situations:
-///
-/// - If the specified CSV file cannot be found, read, or is not valid CSV.
-/// - If an error occurs while parsing the CSV data into the `FileGenerationParams` struct.
-/// - If there is an error in generating files based on the parameters from each CSV record.
-///
-pub fn generate_from_csv(path: &str) -> io::Result<()> {
-    let mut reader = csv::Reader::from_path(path)?;
-    for result in reader.records() {
-        let record = result?;
-        // println!("{:?}", record);
-        let params = FileGenerationParams {
-            author: record.get(0).map(ToString::to_string),
-            build: record.get(1).map(ToString::to_string),
-            categories: record.get(2).map(ToString::to_string),
-            description: record.get(3).map(ToString::to_string),
-            documentation: record.get(4).map(ToString::to_string),
-            edition: record.get(5).map(ToString::to_string),
-            email: record.get(6).map(ToString::to_string),
-            homepage: record.get(7).map(ToString::to_string),
-            keywords: record.get(8).map(ToString::to_string),
-            license: record.get(9).map(ToString::to_string),
-            name: record.get(10).map(ToString::to_string),
-            output: record.get(11).map(ToString::to_string),
-            readme: record.get(12).map(ToString::to_string),
-            repository: record.get(13).map(ToString::to_string),
-            rustversion: record.get(14).map(ToString::to_string),
-            version: record.get(15).map(ToString::to_string),
-            website: record.get(16).map(ToString::to_string),
-        };
-        // println!("Params: {:?}", params);
-        macro_generate_files!(params.clone())
-            .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
-    }
-    Ok(())
-}
-
-/// Generates files for a new Rust project based on a JSON file.
-///
-/// # Arguments
-///
-/// The JSON file must contain a single object with the following
-/// properties:
-///
-/// - `author` - the author of the project (optional).
-/// - `build` - the build command to be used for building the project (optional).
-/// - `categories` - the categories that the project belongs to (optional).
-/// - `description` - a short description of the project (optional).
-/// - `documentation` - the documentation URL of the project (optional).
-/// - `edition` - the edition of the project (optional).
-/// - `email` - the email address of the author (optional).
-/// - `homepage` - the homepage of the project (optional).
-/// - `keywords` - keywords that describe the project (optional).
-/// - `license` - the license under which the project is released (optional).
-/// - `name` - the name of the project (optional).
-/// - `output` - the output directory where the project files will be created (required).
-/// - `readme` - the name of the readme file (optional).
-/// - `repository` - the url of the project's repository (optional).
-/// - `rustversion` - the minimum Rust version required by the project (optional).
-/// - `version` - the initial version of the project (optional).
-/// - `website` - the website of the project (optional).
-///
-/// # Errors
-///
-/// This function will return an error in the following situations:
-///
-/// - If the specified JSON file cannot be found, read, or is not valid UTF-8.
-/// - If the JSON data cannot be deserialized into the `FileGenerationParams` struct.
-/// - If there is an error in generating files based on the parameters.
-///
-pub fn generate_from_json(path: &str) -> io::Result<()> {
-    let contents = fs::read_to_string(path)?;
-    let params: FileGenerationParams = serde_json::from_str(&contents)
-        .map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?;
-    macro_generate_files!(params.clone()).map_err(|e| {
-        io::Error::new(io::ErrorKind::Other, e)
-    })?;
-    Ok(())
-}
-
-/// Generates files for a new Rust project based on a YAML file.
-///
-/// The YAML file must contain a single object with the following
-/// properties:
-///
-/// - `author` - the author of the project (optional).
-/// - `build` - the build command to be used for building the project (optional).
-/// - `categories` - the categories that the project belongs to (optional).
-/// - `description` - a short description of the project (optional).
-/// - `documentation` - the documentation URL of the project (optional).
-/// - `edition` - the edition of the project (optional).
-/// - `email` - the email address of the author (optional).
-/// - `homepage` - the homepage of the project (optional).
-/// - `keywords` - keywords that describe the project (optional).
-/// - `license` - the license under which the project is released (optional).
-/// - `name` - the name of the project (optional).
-/// - `output` - the output directory where the project files will be created (required).
-/// - `readme` - the name of the readme file (optional).
-/// - `repository` - the url of the project's repository (optional).
-/// - `rustversion` - the minimum Rust version required by the project (optional).
-/// - `version` - the initial version of the project (optional).
-/// - `website` - the website of the project (optional).
-///
-/// # Errors
-///
-/// This function will return an error in the following situations:
-///
-/// - If the specified YAML file cannot be found, read, or is not valid UTF-8.
-/// - If the YAML data cannot be deserialized into the `FileGenerationParams` struct.
-/// - If there is an error in generating files based on the parameters.
-///
-pub fn generate_from_yaml(path: &str) -> io::Result<()> {
-    let contents = fs::read_to_string(path)?;
-    let params: FileGenerationParams = serde_yaml::from_str(&contents)
-        .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
-    macro_generate_files!(params.clone()).map_err(|e| {
-        io::Error::new(io::ErrorKind::Other, e)
-    })?;
-    Ok(())
-}
-
-/// Generates files for a new Rust project based on an INI file.
-///
-/// The INI file must contain a single section with the following
-/// keys:
-/// - `author` - the author of the project (optional).
-/// - `build` - the build command to be used for building the project (optional).
-/// - `categories` - the categories that the project belongs to (optional).
-/// - `description` - a short description of the project (optional).
-/// - `documentation` - the documentation URL of the project (optional).
-/// - `edition` - the edition of the project (optional).
-/// - `email` - the email address of the author (optional).
-/// - `homepage` - the homepage of the project (optional).
-/// - `keywords` - keywords that describe the project (optional).
-/// - `license` - the license under which the project is released (optional).
-/// - `name` - the name of the project (optional).
-/// - `output` - the output directory where the project files will be created (required).
-/// - `readme` - the name of the readme file (optional).
-/// - `repository` - the url of the project's repository (optional).
-/// - `rustversion` - the minimum Rust version required by the project (optional).
-/// - `version` - the initial version of the project (optional).
-/// - `website` - the website of the project (optional).
-///
-/// # Errors
-///
-/// This function will return an error in the following situations:
-///
-/// - If the specified INI file cannot be found, read, or is not valid UTF-8.
-/// - If the INI data cannot be parsed into the `FileGenerationParams` struct.
-/// - If there is an error in generating files based on the parameters.
-///
-pub fn generate_from_ini(path: &str) -> io::Result<()> {
-    let contents = fs::read_to_string(path)?;
-    let params: FileGenerationParams = from_str(&contents)
-        .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e.to_string()))?;
-    macro_generate_files!(params.clone()).map_err(|e| {
-        io::Error::new(io::ErrorKind::Other, e)
-    })?;
-    Ok(())
-}
-
-/// Generates files for a new Rust project based on a TOML file.
-///
-/// The TOML file must contain a single object with the following
-/// properties:
-///
-/// - `author` - the author of the project (optional).
-/// - `build` - the build command to be used for building the project (optional).
-/// - `categories` - the categories that the project belongs to (optional).
-/// - `description` - a short description of the project (optional).
-/// - `documentation` - the documentation URL of the project (optional).
-/// - `edition` - the edition of the project (optional).
-/// - `email` - the email address of the author (optional).
-/// - `homepage` - the homepage of the project (optional).
-/// - `keywords` - keywords that describe the project (optional).
-/// - `license` - the license under which the project is released (optional).
-/// - `name` - the name of the project (optional).
-/// - `output` - the output directory where the project files will be created (required).
-/// - `readme` - the name of the readme file (optional).
-/// - `repository` - the url of the project's repository (optional).
-/// - `rustversion` - the minimum Rust version required by the project (optional).
-/// - version - the initial version of the project (optional).
-/// - website - the website of the project (optional).
-///
-/// # Errors
-///
-/// This function will return an error in the following situations:
-///
-/// - If the specified TOML file cannot be found, read, or is not valid UTF-8.
-/// - If the TOML data cannot be deserialized into the FileGenerationParams struct.
-/// - If there is an error in generating files based on the parameters.
-///
-pub fn generate_from_toml(path: &str) -> io::Result<()> {
-    let contents = fs::read_to_string(path)?;
-    let params: FileGenerationParams = toml::from_str(&contents)
-        .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
-    macro_generate_files!(params.clone()).map_err(|e| {
-        io::Error::new(io::ErrorKind::Other, e)
-    })?;
-    Ok(())
-}
-
-/// Generates files for a new Rust project based on command line arguments.
-/// The arguments must be in the form `--name=value`.
-/// The following arguments are supported:
-/// - `author` - the author of the project (optional).
-/// - `build` - the build command to be used for building the project (optional).
-/// - `categories` - the categories that the project belongs to (optional).
-/// - `description` - a short description of the project (optional).
-/// - `documentation` - the documentation URL of the project (optional).
-/// - `edition` - the edition of the project (optional).
-/// - `email` - the email address of the author (optional).
-/// - `homepage` - the homepage of the project (optional).
-/// - `keywords` - keywords that describe the project (optional).
-/// - `license` - the license under which the project is released (optional).
-/// - `name` - the name of the project (optional).
-/// - `output` - the output directory where the project files will be created (required).
-/// - `readme` - the name of the readme file (optional).
-/// - `repository` - the url of the project's repository (optional).
-/// - `rustversion` - the minimum Rust version required by the project (optional).
-/// - `version` - the initial version of the project (optional).
-/// - `website` - the website of the project (optional).
-///
-/// # Errors
-///
-/// This function will return an error in the following situations:
-///
-/// - If an invalid argument is provided. Each argument must be in the form `--name=value`.
-/// - If there is an error in generating files based on the parameters derived from the arguments.
-///
-pub fn generate_from_args(args_str: &str) -> io::Result<()> {
-    let args = args_str.split_whitespace();
-    let mut params = FileGenerationParams::default();
-    for arg in args {
-        let mut parts = arg.splitn(2, '=');
-        let name = parts.next().unwrap_or_default();
-        let value = parts.next().unwrap_or_default();
-        match name {
-            "--author" => params.author = Some(value.to_string()),
-            "--build" => params.build = Some(value.to_string()),
-            "--categories" => {
-                params.categories = Some(value.to_string());
-            }
-            "--description" => {
-                params.description = Some(value.to_string());
-            }
-            "--documentation" => {
-                params.documentation = Some(value.to_string());
-            }
-            "--edition" => params.edition = Some(value.to_string()),
-            "--email" => params.email = Some(value.to_string()),
-            "--homepage" => params.homepage = Some(value.to_string()),
-            "--keywords" => params.keywords = Some(value.to_string()),
-            "--license" => params.license = Some(value.to_string()),
-            "--name" => params.name = Some(value.to_string()),
-            "--output" => params.output = Some(value.to_string()),
-            "--readme" => params.readme = Some(value.to_string()),
-            "--repository" => {
-                params.repository = Some(value.to_string());
-            }
-            "--rustversion" => {
-                params.rustversion = Some(value.to_string());
-            }
-            "--version" => params.version = Some(value.to_string()),
-            "--website" => params.website = Some(value.to_string()),
-            _ => {
-                return Err(io::Error::new(
-                    io::ErrorKind::Other,
-                    format!("Invalid argument: {name}"),
-                ))
-            }
-        }
-    }
-    println!("{params:?}");
-    generate_files(params)?;
-    Ok(())
-}
diff --git a/src/generators/args.rs b/src/generators/args.rs
new file mode 100644
index 0000000..71f7217
--- /dev/null
+++ b/src/generators/args.rs
@@ -0,0 +1,81 @@
+use crate::{
+    generator::generate_files,
+    models::model_params::FileGenerationParams,
+};
+use std::io;
+
+/// Generates files for a new Rust project based on command line arguments.
+/// The arguments must be in the form `--name=value`.
+/// The following arguments are supported:
+/// - `author` - the author of the project (optional).
+/// - `build` - the build command to be used for building the project (optional).
+/// - `categories` - the categories that the project belongs to (optional).
+/// - `description` - a short description of the project (optional).
+/// - `documentation` - the documentation URL of the project (optional).
+/// - `edition` - the edition of the project (optional).
+/// - `email` - the email address of the author (optional).
+/// - `homepage` - the homepage of the project (optional).
+/// - `keywords` - keywords that describe the project (optional).
+/// - `license` - the license under which the project is released (optional).
+/// - `name` - the name of the project (optional).
+/// - `output` - the output directory where the project files will be created (required).
+/// - `readme` - the name of the readme file (optional).
+/// - `repository` - the url of the project's repository (optional).
+/// - `rustversion` - the minimum Rust version required by the project (optional).
+/// - `version` - the initial version of the project (optional).
+/// - `website` - the website of the project (optional).
+///
+/// # Errors
+///
+/// This function will return an error in the following situations:
+///
+/// - If an invalid argument is provided. Each argument must be in the form `--name=value`.
+/// - If there is an error in generating files based on the parameters derived from the arguments.
+///
+pub fn generate_from_args(args_str: &str) -> io::Result<()> {
+    let args = args_str.split_whitespace();
+    let mut params = FileGenerationParams::default();
+    for arg in args {
+        let mut parts = arg.splitn(2, '=');
+        let name = parts.next().unwrap_or_default();
+        let value = parts.next().unwrap_or_default();
+        match name {
+            "--author" => params.author = Some(value.to_string()),
+            "--build" => params.build = Some(value.to_string()),
+            "--categories" => {
+                params.categories = Some(value.to_string());
+            }
+            "--description" => {
+                params.description = Some(value.to_string());
+            }
+            "--documentation" => {
+                params.documentation = Some(value.to_string());
+            }
+            "--edition" => params.edition = Some(value.to_string()),
+            "--email" => params.email = Some(value.to_string()),
+            "--homepage" => params.homepage = Some(value.to_string()),
+            "--keywords" => params.keywords = Some(value.to_string()),
+            "--license" => params.license = Some(value.to_string()),
+            "--name" => params.name = Some(value.to_string()),
+            "--output" => params.output = Some(value.to_string()),
+            "--readme" => params.readme = Some(value.to_string()),
+            "--repository" => {
+                params.repository = Some(value.to_string());
+            }
+            "--rustversion" => {
+                params.rustversion = Some(value.to_string());
+            }
+            "--version" => params.version = Some(value.to_string()),
+            "--website" => params.website = Some(value.to_string()),
+            _ => {
+                return Err(io::Error::new(
+                    io::ErrorKind::Other,
+                    format!("Invalid argument: {name}"),
+                ))
+            }
+        }
+    }
+    println!("{params:?}");
+    generate_files(params)?;
+    Ok(())
+}
diff --git a/src/generators/csv.rs b/src/generators/csv.rs
new file mode 100644
index 0000000..64dd32a
--- /dev/null
+++ b/src/generators/csv.rs
@@ -0,0 +1,65 @@
+use std::io;
+use csv::Reader;
+use crate::models::model_params::FileGenerationParams;
+use crate::macro_generate_files;
+
+/// Generates files for a new Rust project based on a CSV file.
+///
+/// # Arguments
+///
+/// The CSV file must contain the following columns:
+///
+/// - `author` - the author of the project (optional).
+/// - `build` - the build command to be used for building the project (optional).
+/// - `categories` - the categories that the project belongs to (optional).
+/// - `description` - a short description of the project (optional).
+/// - `documentation` - the documentation URL of the project (optional).
+/// - `edition` - the edition of the project (optional).
+/// - `email` - the email address of the author (optional).
+/// - `homepage` - the homepage of the project (optional).
+/// - `keywords` - keywords that describe the project (optional).
+/// - `license` - the license under which the project is released (optional).
+/// - `name` - the name of the project (optional).
+/// - `output` - the output directory where the project files will be created (required).
+/// - `readme` - the name of the readme file (optional).
+/// - `repository` - the url of the project's repository (optional).
+/// - `rustversion` - the minimum Rust version required by the project (optional).
+/// - `version` - the initial version of the project (optional).
+/// - `website` - the website of the project (optional).
+///
+/// # Errors
+///
+/// This function will return an error in the following situations:
+///
+/// - If the specified CSV file cannot be found, read, or is not valid CSV.
+/// - If an error occurs while parsing the CSV data into the `FileGenerationParams` struct.
+/// - If there is an error in generating files based on the parameters from each CSV record.
+///
+pub fn generate_from_csv(path: &str) -> io::Result<()> {
+    let mut reader = Reader::from_path(path)?;
+    for result in reader.records() {
+        let record = result?;
+        let params = FileGenerationParams {
+            author: record.get(0).map(ToString::to_string),
+            build: record.get(1).map(ToString::to_string),
+            categories: record.get(2).map(ToString::to_string),
+            description: record.get(3).map(ToString::to_string),
+            documentation: record.get(4).map(ToString::to_string),
+            edition: record.get(5).map(ToString::to_string),
+            email: record.get(6).map(ToString::to_string),
+            homepage: record.get(7).map(ToString::to_string),
+            keywords: record.get(8).map(ToString::to_string),
+            license: record.get(9).map(ToString::to_string),
+            name: record.get(10).map(ToString::to_string),
+            output: record.get(11).map(ToString::to_string),
+            readme: record.get(12).map(ToString::to_string),
+            repository: record.get(13).map(ToString::to_string),
+            rustversion: record.get(14).map(ToString::to_string),
+            version: record.get(15).map(ToString::to_string),
+            website: record.get(16).map(ToString::to_string),
+        };
+        macro_generate_files!(params.clone())
+            .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
+    }
+    Ok(())
+}
diff --git a/src/generators/ini.rs b/src/generators/ini.rs
new file mode 100644
index 0000000..9962912
--- /dev/null
+++ b/src/generators/ini.rs
@@ -0,0 +1,45 @@
+use std::fs;
+use std::io;
+use serde_ini::from_str;
+use crate::models::model_params::FileGenerationParams;
+use crate::macro_generate_files;
+
+/// Generates files for a new Rust project based on an INI file.
+///
+/// The INI file must contain a single section with the following
+/// keys:
+/// - `author` - the author of the project (optional).
+/// - `build` - the build command to be used for building the project (optional).
+/// - `categories` - the categories that the project belongs to (optional).
+/// - `description` - a short description of the project (optional).
+/// - `documentation` - the documentation URL of the project (optional).
+/// - `edition` - the edition of the project (optional).
+/// - `email` - the email address of the author (optional).
+/// - `homepage` - the homepage of the project (optional).
+/// - `keywords` - keywords that describe the project (optional).
+/// - `license` - the license under which the project is released (optional).
+/// - `name` - the name of the project (optional).
+/// - `output` - the output directory where the project files will be created (required).
+/// - `readme` - the name of the readme file (optional).
+/// - `repository` - the url of the project's repository (optional).
+/// - `rustversion` - the minimum Rust version required by the project (optional).
+/// - `version` - the initial version of the project (optional).
+/// - `website` - the website of the project (optional).
+///
+/// # Errors
+///
+/// This function will return an error in the following situations:
+///
+/// - If the specified INI file cannot be found, read, or is not valid UTF-8.
+/// - If the INI data cannot be parsed into the `FileGenerationParams` struct.
+/// - If there is an error in generating files based on the parameters.
+///
+pub fn generate_from_ini(path: &str) -> io::Result<()> {
+    let contents = fs::read_to_string(path)?;
+    let params: FileGenerationParams = from_str(&contents)
+        .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e.to_string()))?;
+    macro_generate_files!(params.clone()).map_err(|e| {
+        io::Error::new(io::ErrorKind::Other, e)
+    })?;
+    Ok(())
+}
diff --git a/src/generators/json.rs b/src/generators/json.rs
new file mode 100644
index 0000000..d6c855a
--- /dev/null
+++ b/src/generators/json.rs
@@ -0,0 +1,47 @@
+use std::fs;
+use std::io;
+use crate::models::model_params::FileGenerationParams;
+use crate::macro_generate_files;
+
+/// Generates files for a new Rust project based on a JSON file.
+///
+/// # Arguments
+///
+/// The JSON file must contain a single object with the following
+/// properties:
+///
+/// - `author` - the author of the project (optional).
+/// - `build` - the build command to be used for building the project (optional).
+/// - `categories` - the categories that the project belongs to (optional).
+/// - `description` - a short description of the project (optional).
+/// - `documentation` - the documentation URL of the project (optional).
+/// - `edition` - the edition of the project (optional).
+/// - `email` - the email address of the author (optional).
+/// - `homepage` - the homepage of the project (optional).
+/// - `keywords` - keywords that describe the project (optional).
+/// - `license` - the license under which the project is released (optional).
+/// - `name` - the name of the project (optional).
+/// - `output` - the output directory where the project files will be created (required).
+/// - `readme` - the name of the readme file (optional).
+/// - `repository` - the url of the project's repository (optional).
+/// - `rustversion` - the minimum Rust version required by the project (optional).
+/// - `version` - the initial version of the project (optional).
+/// - `website` - the website of the project (optional).
+///
+/// # Errors
+///
+/// This function will return an error in the following situations:
+///
+/// - If the specified JSON file cannot be found, read, or is not valid UTF-8.
+/// - If the JSON data cannot be deserialized into the `FileGenerationParams` struct.
+/// - If there is an error in generating files based on the parameters.
+///
+pub fn generate_from_json(path: &str) -> io::Result<()> {
+    let contents = fs::read_to_string(path)?;
+    let params: FileGenerationParams = serde_json::from_str(&contents)
+        .map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?;
+    macro_generate_files!(params.clone()).map_err(|e| {
+        io::Error::new(io::ErrorKind::Other, e)
+    })?;
+    Ok(())
+}
diff --git a/src/generators/mod.rs b/src/generators/mod.rs
index 68ac673..488278a 100644
--- a/src/generators/mod.rs
+++ b/src/generators/mod.rs
@@ -3,5 +3,24 @@
 // SPDX-License-Identifier: Apache-2.0 OR MIT indicates dual licensing under Apache 2.0 or MIT licenses.
 // Copyright © 2024 LibMake. All rights reserved.
 
-/// The `ascii` module contains functionality for generating ASCII art from text using the FIGlet library.
+/// The `ascii` module contains functionality for generating ASCII art from
+/// text using the FIGlet library.
 pub mod ascii;
+
+/// The `args` module contains functionality for parsing command-line arguments.
+pub mod args;
+
+/// The `csv` module contains functionality for parsing CSV files.
+pub mod csv;
+
+/// The `ini` module contains functionality for parsing INI files.
+pub mod ini;
+
+/// The `json` module contains functionality for parsing JSON files.
+pub mod json;
+
+/// The `toml` module contains functionality for parsing TOML files.
+pub mod toml;
+
+/// The `yaml` module contains functionality for parsing YAML files.
+pub mod yaml;
diff --git a/src/generators/toml.rs b/src/generators/toml.rs
new file mode 100644
index 0000000..41b36c7
--- /dev/null
+++ b/src/generators/toml.rs
@@ -0,0 +1,45 @@
+use std::fs;
+use std::io;
+use crate::models::model_params::FileGenerationParams;
+use crate::macro_generate_files;
+
+/// Generates files for a new Rust project based on a TOML file.
+///
+/// The TOML file must contain a single object with the following
+/// properties:
+///
+/// - `author` - the author of the project (optional).
+/// - `build` - the build command to be used for building the project (optional).
+/// - `categories` - the categories that the project belongs to (optional).
+/// - `description` - a short description of the project (optional).
+/// - `documentation` - the documentation URL of the project (optional).
+/// - `edition` - the edition of the project (optional).
+/// - `email` - the email address of the author (optional).
+/// - `homepage` - the homepage of the project (optional).
+/// - `keywords` - keywords that describe the project (optional).
+/// - `license` - the license under which the project is released (optional).
+/// - `name` - the name of the project (optional).
+/// - `output` - the output directory where the project files will be created (required).
+/// - `readme` - the name of the readme file (optional).
+/// - `repository` - the url of the project's repository (optional).
+/// - `rustversion` - the minimum Rust version required by the project (optional).
+/// - version - the initial version of the project (optional).
+/// - website - the website of the project (optional).
+///
+/// # Errors
+///
+/// This function will return an error in the following situations:
+///
+/// - If the specified TOML file cannot be found, read, or is not valid UTF-8.
+/// - If the TOML data cannot be deserialized into the FileGenerationParams struct.
+/// - If there is an error in generating files based on the parameters.
+///
+pub fn generate_from_toml(path: &str) -> io::Result<()> {
+    let contents = fs::read_to_string(path)?;
+    let params: FileGenerationParams = toml::from_str(&contents)
+        .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
+    macro_generate_files!(params.clone()).map_err(|e| {
+        io::Error::new(io::ErrorKind::Other, e)
+    })?;
+    Ok(())
+}
diff --git a/src/generators/yaml.rs b/src/generators/yaml.rs
new file mode 100644
index 0000000..42ee3d0
--- /dev/null
+++ b/src/generators/yaml.rs
@@ -0,0 +1,45 @@
+use std::fs;
+use std::io;
+use crate::models::model_params::FileGenerationParams;
+use crate::macro_generate_files;
+
+/// Generates files for a new Rust project based on a YAML file.
+///
+/// The YAML file must contain a single object with the following
+/// properties:
+///
+/// - `author` - the author of the project (optional).
+/// - `build` - the build command to be used for building the project (optional).
+/// - `categories` - the categories that the project belongs to (optional).
+/// - `description` - a short description of the project (optional).
+/// - `documentation` - the documentation URL of the project (optional).
+/// - `edition` - the edition of the project (optional).
+/// - `email` - the email address of the author (optional).
+/// - `homepage` - the homepage of the project (optional).
+/// - `keywords` - keywords that describe the project (optional).
+/// - `license` - the license under which the project is released (optional).
+/// - `name` - the name of the project (optional).
+/// - `output` - the output directory where the project files will be created (required).
+/// - `readme` - the name of the readme file (optional).
+/// - `repository` - the url of the project's repository (optional).
+/// - `rustversion` - the minimum Rust version required by the project (optional).
+/// - `version` - the initial version of the project (optional).
+/// - `website` - the website of the project (optional).
+///
+/// # Errors
+///
+/// This function will return an error in the following situations:
+///
+/// - If the specified YAML file cannot be found, read, or is not valid UTF-8.
+/// - If the YAML data cannot be deserialized into the `FileGenerationParams` struct.
+/// - If there is an error in generating files based on the parameters.
+///
+pub fn generate_from_yaml(path: &str) -> io::Result<()> {
+    let contents = fs::read_to_string(path)?;
+    let params: FileGenerationParams = serde_yaml::from_str(&contents)
+        .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
+    macro_generate_files!(params.clone()).map_err(|e| {
+        io::Error::new(io::ErrorKind::Other, e)
+    })?;
+    Ok(())
+}
diff --git a/src/interface.rs b/src/interface.rs
index fae9ae8..a4ae0b2 100644
--- a/src/interface.rs
+++ b/src/interface.rs
@@ -8,8 +8,7 @@ use std::{
     io::{BufRead, BufReader, Write},
     path::PathBuf,
 };
-
-use super::generator::FileGenerationParams;
+use crate::models::model_params::FileGenerationParams;
 use crate::macro_replace_placeholder;
 
 /// Replaces placeholders in a template file with values from the provided parameters
diff --git a/src/macros/generator_macros.rs b/src/macros/generator_macros.rs
index ca34dac..c519fa5 100644
--- a/src/macros/generator_macros.rs
+++ b/src/macros/generator_macros.rs
@@ -46,7 +46,7 @@ macro_rules! macro_generate_files {
 /// If successful, returns `Ok(())`. If an error occurs, returns `Err` with an error message.
 macro_rules! macro_generate_from_csv {
     ($csv_path:expr) => {{
-        use $crate::generator::generate_from_csv;
+        use $crate::generators::csv::generate_from_csv;
         match generate_from_csv($csv_path) {
             Ok(_) => Ok(()),
             Err(e) => Err(format!("Failed to generate files from CSV at: {} - Error: {}", $csv_path, e)),
@@ -67,7 +67,7 @@ macro_rules! macro_generate_from_csv {
 /// If successful, returns `Ok(())`. If an error occurs, returns `Err` with an error message.
 macro_rules! macro_generate_from_ini {
     ($ini_path:expr) => {{
-        use $crate::generator::generate_from_ini;
+        use $crate::generators::ini::generate_from_ini;
         match generate_from_ini($ini_path) {
             Ok(_) => Ok(()),
             Err(e) => Err(format!("Failed to generate files from INI at: {} - Error: {}", $ini_path, e)),
@@ -88,7 +88,7 @@ macro_rules! macro_generate_from_ini {
 /// If successful, returns `Ok(())`. If an error occurs, returns `Err` with an error message.
 macro_rules! macro_generate_from_json {
     ($json_path:expr) => {{
-        use $crate::generator::generate_from_json;
+        use $crate::generators::json::generate_from_json;
         match generate_from_json($json_path) {
             Ok(_) => Ok(()),
             Err(e) => Err(format!("Failed to generate files from JSON at: {} - Error: {}", $json_path, e)),
@@ -109,7 +109,7 @@ macro_rules! macro_generate_from_json {
 /// If successful, returns `Ok(())`. If an error occurs, returns `Err` with an error message.
 macro_rules! macro_generate_from_toml {
     ($toml_path:expr) => {{
-        use $crate::generator::generate_from_toml;
+        use $crate::generators::toml::generate_from_toml;
         match generate_from_toml($toml_path) {
             Ok(_) => Ok(()),
             Err(e) => Err(format!("Failed to generate files from TOML at: {} - Error: {}", $toml_path, e)),
@@ -130,7 +130,7 @@ macro_rules! macro_generate_from_toml {
 /// If successful, returns `Ok(())`. If an error occurs, returns `Err` with an error message.
 macro_rules! macro_generate_from_yaml {
     ($yaml_path:expr) => {{
-        use $crate::generator::generate_from_yaml;
+        use $crate::generators::yaml::generate_from_yaml;
         match generate_from_yaml($yaml_path) {
             Ok(_) => Ok(()),
             Err(e) => Err(format!("Failed to generate files from YAML at: {} - Error: {}", $yaml_path, e)),
@@ -151,7 +151,7 @@ macro_rules! macro_generate_from_yaml {
 /// If successful, returns `Ok(())`. If an error occurs, returns `Err` with an error message.
 macro_rules! macro_generate_from_args {
     ($args:expr) => {{
-        use $crate::generator::generate_from_args;
+        use $crate::generators::args::generate_from_args;
         match generate_from_args($args) {
             Ok(_) => Ok(()),
             Err(e) => Err(format!("Failed to generate files from arguments: {:?} - Error: {}", $args, e)),
diff --git a/src/models/mod.rs b/src/models/mod.rs
index cb65dda..72e6ab4 100644
--- a/src/models/mod.rs
+++ b/src/models/mod.rs
@@ -5,3 +5,6 @@
 
 /// The `ascii_art_error` module contains the `AsciiArtError` type for ASCII art generation failures.
 pub mod error_ascii_art;
+
+/// The `model_params` module contains the `FileGenerationParams` type for holding the parameters for generating the project files.
+pub mod model_params;
diff --git a/src/models/model_params.rs b/src/models/model_params.rs
new file mode 100644
index 0000000..99f7f83
--- /dev/null
+++ b/src/models/model_params.rs
@@ -0,0 +1,181 @@
+// Copyright notice and licensing information.
+// These lines indicate the copyright of the software and its licensing terms.
+// SPDX-License-Identifier: Apache-2.0 OR MIT indicates dual licensing under Apache 2.0 or MIT licenses.
+// Copyright © 2024 LibMake. All rights reserved.
+
+use serde::{Deserialize, Serialize};
+
+/// Structure for holding the parameters for generating the project files.
+///
+/// # Description
+///
+/// * The `output` directory is the directory where the project files will be created.
+/// * The other parameters are optional and will be used to replace the placeholders in the template files.
+/// * The template files are located in the template directory of the project.
+/// * The template files are copied to the output directory and the placeholders are replaced with the values of the parameters.
+///
+#[derive(
+    Clone,
+    Debug,
+    Default,
+    Deserialize,
+    Eq,
+    Hash,
+    Ord,
+    PartialEq,
+    PartialOrd,
+    Serialize,
+)]
+pub struct FileGenerationParams {
+    /// The author of the project (optional).
+    pub author: Option<String>,
+    /// The build command to be used for building the project (optional).
+    pub build: Option<String>,
+    /// The categories that the project belongs to (optional).
+    pub categories: Option<String>,
+    /// A short description of the project (optional).
+    pub description: Option<String>,
+    /// The documentation URL of the project (optional).
+    pub documentation: Option<String>,
+    /// The edition of the project (optional).
+    pub edition: Option<String>,
+    /// The email address of the author (optional).
+    pub email: Option<String>,
+    /// The homepage of the project (optional).
+    pub homepage: Option<String>,
+    /// Keywords that describe the project (optional).
+    pub keywords: Option<String>,
+    /// The license under which the project is released (optional).
+    pub license: Option<String>,
+    /// The name of the project (optional).
+    pub name: Option<String>,
+    /// The output directory where the project files will be created (optional).
+    pub output: Option<String>,
+    /// The name of the readme file (optional).
+    pub readme: Option<String>,
+    /// The URL of the project's repository (optional).
+    pub repository: Option<String>,
+    /// The minimum Rust version required by the project (optional).
+    pub rustversion: Option<String>,
+    /// The initial version of the project (optional).
+    pub version: Option<String>,
+    /// The website of the project (optional).
+    pub website: Option<String>,
+}
+
+impl FileGenerationParams {
+    /// Creates a default instance with default values for all fields.
+    /// Fields that are truly optional without a default are initialized as `None`.
+    pub fn default_params() -> Self {
+        Self {
+            author: Some("John Smith".to_string()),
+            build: Some("build.rs".to_string()),
+            categories: Some(
+                "[\"category1\",\"category2\",\"category3\"]"
+                    .to_string(),
+            ),
+            description: Some(
+                "A Rust library for doing cool things".to_string(),
+            ),
+            documentation: Some(
+                "https://docs.rs/my_library".to_string(),
+            ),
+            edition: Some("2021".to_string()),
+            email: Some("john.smith@example.com".to_string()),
+            homepage: Some("https://my_library.rs".to_string()),
+            keywords: Some(
+                "[\"rust\",\"library\",\"cool\"]".to_string(),
+            ),
+            license: Some("MIT".to_string()),
+            name: Some("my_library".to_string()),
+            output: Some("my_library".to_string()),
+            readme: Some("README.md".to_string()),
+            repository: Some(
+                "https://github.com/example/my_library".to_string(),
+            ),
+            rustversion: Some("1.75.0".to_string()),
+            version: Some("0.1.0".to_string()),
+            website: Some("https://example.com/john-smith".to_string()),
+        }
+    }
+    /// Parses the command line arguments and returns a new instance of
+    /// the structure.
+
+    /// Creates a new instance with default values.
+    pub fn new() -> Self {
+        Self::default_params()
+    }
+    /// Parses the command line arguments and returns a new instance of
+    /// the structure.
+    ///
+    /// # Arguments
+    /// * `args_str` - A string slice containing the command line arguments.
+    ///
+    /// # Errors
+    /// Returns an `Err` if the arguments are not in the expected format
+    /// or if mandatory arguments are missing. The error is a `String`
+    /// describing what went wrong.
+    ///
+    pub fn from_args(args_str: &str) -> Result<Self, String> {
+        let mut params = Self::new();
+        let args: Vec<&str> = args_str.split_whitespace().collect();
+        for arg in args {
+            let mut arg_parts = arg.splitn(2, ' ');
+            let arg_name = arg_parts
+                .next()
+                .ok_or_else(|| "Missing argument name".to_string())?;
+            let arg_value = arg_parts
+                .next()
+                .ok_or_else(|| "Missing argument value".to_string())?;
+            match arg_name {
+                "--author" => {
+                    params.author = Some(arg_value.to_string());
+                }
+                "--build" => params.build = Some(arg_value.to_string()),
+                "--categories" => {
+                    params.categories = Some(arg_value.to_string());
+                }
+                "--description" => {
+                    params.description = Some(arg_value.to_string());
+                }
+                "--documentation" => {
+                    params.documentation = Some(arg_value.to_string());
+                }
+                "--edition" => {
+                    params.edition = Some(arg_value.to_string());
+                }
+                "--email" => params.email = Some(arg_value.to_string()),
+                "--homepage" => {
+                    params.homepage = Some(arg_value.to_string());
+                }
+                "--keywords" => {
+                    params.keywords = Some(arg_value.to_string());
+                }
+                "--license" => {
+                    params.license = Some(arg_value.to_string());
+                }
+                "--name" => params.name = Some(arg_value.to_string()),
+                "--output" => {
+                    params.output = Some(arg_value.to_string());
+                }
+                "--readme" => {
+                    params.readme = Some(arg_value.to_string());
+                }
+                "--repository" => {
+                    params.repository = Some(arg_value.to_string());
+                }
+                "--rustversion" => {
+                    params.rustversion = Some(arg_value.to_string());
+                }
+                "--version" => {
+                    params.version = Some(arg_value.to_string());
+                }
+                "--website" => {
+                    params.website = Some(arg_value.to_string());
+                }
+                _ => (),
+            }
+        }
+        Ok(params)
+    }
+}
diff --git a/src/parser.rs b/src/parser.rs
deleted file mode 100644
index 3bf44f5..0000000
--- a/src/parser.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright notice and licensing information.
-// These lines indicate the copyright of the software and its licensing terms.
-// SPDX-License-Identifier: Apache-2.0 OR MIT indicates dual licensing under Apache 2.0 or MIT licenses.
-// Copyright © 2024 LibMake. All rights reserved.
-
-/// A macro for getting a configuration field from a configuration file.
-pub mod get_config_field;
-
-/// A macro for getting a field from a CSV file.
-pub mod get_csv_field;
-
-/// A macro for getting a field from a JSON file.
-pub mod get_json_field;
-
-/// A macro for getting a field from a TOML file.
-pub mod get_yaml_field;
diff --git a/src/utils.rs b/src/utils.rs
index e904c83..ed3eb63 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -3,9 +3,13 @@
 // SPDX-License-Identifier: Apache-2.0 OR MIT indicates dual licensing under Apache 2.0 or MIT licenses.
 // Copyright © 2024 LibMake. All rights reserved.
 
-use std::{env, fs::File, path::Path};
 use crate::macro_get_field;
-
+use std::{
+    env,
+    fs::{self, File},
+    io,
+    path::Path,
+};
 
 /// Reads a file and deserializes its content using the specified deserializer function.
 ///
@@ -102,3 +106,22 @@ pub fn get_config_field(
         .into()),
     }
 }
+
+/// Creates a directory at the specified path.
+///
+/// # Arguments
+///
+/// * `path` - The path where the directory should be created.
+///
+/// # Errors
+///
+/// Returns an `io::Error` if the directory cannot be created. This could be due to
+/// various reasons such as insufficient permissions, the directory already existing,
+/// or other I/O-related errors.
+///
+pub fn create_directory(path: &Path) -> io::Result<()> {
+    fs::create_dir(path).or_else(|e| match e.kind() {
+        io::ErrorKind::AlreadyExists => Ok(()),
+        _ => Err(e),
+    })
+}
diff --git a/tests/test_args.rs b/tests/test_args.rs
index ca52ce8..9a2af70 100644
--- a/tests/test_args.rs
+++ b/tests/test_args.rs
@@ -1,8 +1,7 @@
 use clap::{Arg, Command};
-use libmake::args::extract_manual_params;
 use libmake::{
-    args::{process_arguments, validate_params},
-    generator::FileGenerationParams,
+    args::{extract_manual_params, process_arguments, validate_params},
+    models::model_params::FileGenerationParams
 };
 
 // Tests the process_arguments function with valid arguments
diff --git a/tests/test_generator.rs b/tests/test_generator.rs
index 017cad2..e13015d 100644
--- a/tests/test_generator.rs
+++ b/tests/test_generator.rs
@@ -1,12 +1,11 @@
-use libmake::generator::{
-    create_directory, generate_from_args,
-};
 use libmake::{
+    generator::generate_from_config,
+    generators::{args::generate_from_args, yaml::generate_from_yaml},
     macro_generate_files,
-    generator::{
-        generate_from_config, generate_from_yaml, FileGenerationParams,
+    models::model_params::FileGenerationParams,
+    utils::{
+        create_directory, get_csv_field, get_json_field, get_yaml_field,
     },
-    utils::{get_csv_field, get_json_field, get_yaml_field},
 };
 use tempfile::tempdir;
 
diff --git a/tests/test_macros.rs b/tests/test_macros.rs
index 4665061..bbf934a 100644
--- a/tests/test_macros.rs
+++ b/tests/test_macros.rs
@@ -1,7 +1,7 @@
 #[cfg(test)]
 mod tests {
 
-    use libmake::generator::FileGenerationParams;
+    use libmake::models::model_params::FileGenerationParams;
     use std::path::Path;
 
     use libmake::macro_create_directories;