commit 0dcaf740aa36df70b07db58124b96b79403a1ba0
Author: ElBe <90863907+ElBe-Plaq@users.noreply.github.com>
Date: Tue Oct 24 09:33:46 2023 +0200
Update to version 1.0.0
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..c7e631c
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,18 @@
+# Editorconfig to keep settings the same across devices and editors
+# https://editorconfig.org/
+
+root = true
+
+[*]
+charset = utf-8
+indent_style = tab
+insert_final_newline = true
+tab_width = 4
+trim_trailing_whitespace = true
+
+[*.{html,md,py,rs}]
+indent_size = 4
+indent_style = space
+
+[*.{yml,yaml}]
+indent_style = space
diff --git a/.github/.gitlint b/.github/.gitlint
new file mode 100644
index 0000000..9755ab3
--- /dev/null
+++ b/.github/.gitlint
@@ -0,0 +1,2 @@
+[general]
+ignore=B6
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 0000000..88d7df4
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1,2 @@
+# Global owner
+* @ElBe-Plaq
diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..defbeba
--- /dev/null
+++ b/.github/CODE_OF_CONDUCT.md
@@ -0,0 +1,121 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement on
+[our discord server](https://discord.gg/JVyyDukQqV).
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/version/2/0/code_of_conduct.html),
+version 2.0, available at
+[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html](https://www.contributor-covenant.org/version/2/0/code_of_conduct.html).
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct
+enforcement ladder](https://github.com/mozilla/diversity).
+
+For answers to common questions about this code of conduct, see the FAQ at
+[https://www.contributor-covenant.org/faq](https://www.contributor-covenant.org/faq). Translations are available at
+[https://www.contributor-covenant.org/translations](https://www.contributor-covenant.org/translations).
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
new file mode 100644
index 0000000..d245223
--- /dev/null
+++ b/.github/CONTRIBUTING.md
@@ -0,0 +1,29 @@
+# How to contribute to this project
+
+Did you find a bug? You want to have a feature implemented? You made code better?
+Please follow the instructions below on how to contribute to this project.
+
+## Notes
+
+Please do **not** report an issue of pull request if the issue is a security vulnerability.
+There is a different way to report such issues. Issues or pull requests about a vulnerability will be removed.
+
+
+
Report vulnerabilities here
+
+
+## Contributing
+
+For any issues or proposals, open an issue. If you already wrote your proposed change(s), please open an issue
+and a pull request. See below for making changes on your own.
+
+### Making changes on your own
+
+1. Create a new issue with a summary of your proposed changes and more.
+2. Fork the repository.
+3. Implement your changes
+4. Test your changes. Run `cargo fmt`, `cargo check` and `cargo clippy` to verify it works.
+5. Create a pull request from your fork.
+6. If it gets accepted, your changes will be in the next release.
+
+To everyone who has reported issues, proposed changes or just helped with peoples questions: Thank you!
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..fa8cce5
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,2 @@
+---
+ko_fi: elbeplaq
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000..161380c
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,33 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: "[BUG] TITLE"
+labels: Bug
+assignees: ElBe-Plaq
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Desktop (please complete the following information):**
+
+- OS: [e.g. iOS]
+- Rust version [eg. 1.69]
+- Version [e.g. 22]
+
+**Additional context**
+Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000..a61c085
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,6 @@
+---
+blank_issues_enabled: false
+contact_links:
+ - name: Discord Server
+ url: https://discord.gg/JVyyDukQqV
+ about: Please ask and answer questions here or just chat with the communtiy.
diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md
new file mode 100644
index 0000000..d45d81d
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/documentation.md
@@ -0,0 +1,7 @@
+---
+name: Documentation
+about: Improvements to the documentation.
+title: "[DOCUMENTATION] TITLE"
+labels: Documentation
+assignees: ElBe-Plaq
+---
diff --git a/.github/ISSUE_TEMPLATE/enhancement.md b/.github/ISSUE_TEMPLATE/enhancement.md
new file mode 100644
index 0000000..54731f2
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/enhancement.md
@@ -0,0 +1,7 @@
+---
+name: Enhancement
+about: Improves something already existing.
+title: "[ENHANCEMENT] TITLE"
+labels: Enhancement
+assignees: ElBe-Plaq
+---
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..36492b6
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,19 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: "[FEATURE] TITLE"
+labels: Feature request
+assignees: ElBe-Plaq
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..6f9b702
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,26 @@
+# Description
+
+Summary of all the changes made.
+
+Closes #(issues that get closed, if this pull request gets closed)
+
+## Type of change
+
+
+
+- [ ] Bug fix (non-breaking change which fixes an issue)
+- [ ] New feature (non-breaking change which adds functionality)
+- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
+- [ ] This change requires a documentation update
+- [ ] Something else
+
+# Checklist:
+
+- [ ] My code follows the style guidelines of this project
+- [ ] I have performed a self-review of my code
+- [ ] I have commented my code, particularly in hard-to-understand areas
+- [ ] I have made corresponding changes to the documentation
+- [ ] My changes generate no new errors or linter warnings
+- [ ] My changes generate no problems with other code
+- [ ] I have added tests that prove my fix is effective or that my feature works
+- [ ] New and existing tests passed locally with my changes
diff --git a/.github/README.md b/.github/README.md
new file mode 100644
index 0000000..9bf9fbe
--- /dev/null
+++ b/.github/README.md
@@ -0,0 +1,86 @@
+
+ logging-rs
+
+
+ logging-rs helps you add logging to your projects using simple macros.
+
+
+
+
+
+
+
+
+
+
+## About this project
+
+logging-rs helps you add logging to your projects using simple macros.
+
+## Installing
+
+Run the following command to add the package to your dependencies:
+
+```bash
+
+$ cargo add logging-rs
+...
+
+```
+
+### Git
+
+To clone the repository locally using git run `git clone https://github.com/ElBe-Development/logging-rs.git`.
+
+## Usage
+
+To use logging-rs you need a configuration. It's best to keep it the same across multiple files. You then need to follow these steps:
+
+1. Import the logging-rs crate:
+
+ ```rust,ignore
+ use logging_rs;
+ ```
+
+2. Create a new logger object:
+
+ ```rust,ignore
+ let logger = logging_rs::Logger::new(logging_rs::Formatter::default(), vec![logging_rs::Output::STDOUT]);
+ ```
+
+3. Log the messages you want to log:
+
+ ```rust,ignore
+ logging_rs::debug!(logger, "Debug message");
+ logging_rs::info!(logger, "Info");
+ logging_rs::warn!(logger, "Warning");
+ logging_rs::error!(logger, "Error!");
+ logging_rs::fatal!(logger, "Fatal error!");
+ logging_rs::log!(logger, "Log message");
+ ```
+
+## Example
+
+With the following rust code:
+
+```rust,ignore
+use logging_rs;
+
+fn main() {
+ let logger = logging_rs::Logger::default();
+
+ logging_rs::debug!(logger, "Debug message");
+}
+```
+
+You will get the following output:
+
+```bash
+[TIMESTAMP] [DEBUG] src\main.rs: Debug message
+```
+
+Where `TIMESTAMP` is the current timestamp.
+
+## Contact
+
+To contact us, get help or just chat with others, you can visit [our discord server](https://discord.gg/JVyyDukQqV).
diff --git a/.github/SECURITY.md b/.github/SECURITY.md
new file mode 100644
index 0000000..7466632
--- /dev/null
+++ b/.github/SECURITY.md
@@ -0,0 +1,14 @@
+# Security Policy
+
+## Supported Versions
+
+| Version | Supported |
+| -------- | ------------------ |
+| `v1.0.0` | :white_check_mark: |
+
+## Reporting a Vulnerability
+
+To report a vulnerability, go to [our discord server](https://discord.gg/JVyyDukQqV), write an
+[E-Mail](mailto:elbe.dev.plaq@gmail.com) or report it via
+[GitHubs security reporting system](https://github.com/ElBe-Development/logging-rs/security/advisories/new)
+(preferred).
diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md
new file mode 100644
index 0000000..cde36fa
--- /dev/null
+++ b/.github/SUPPORT.md
@@ -0,0 +1,7 @@
+# Support
+
+You can get support on:
+
+- [our discord server](https://discord.gg/JVyyDukQqV)
+- [GitHub discussions](https://github.com/ElBe-Development/logging-rs/discussions)
+- [GitHub issues](https://github.com/ElBe-Development/logging-rs/issues)
diff --git a/.github/auto_assign.yml b/.github/auto_assign.yml
new file mode 100644
index 0000000..fb03d3c
--- /dev/null
+++ b/.github/auto_assign.yml
@@ -0,0 +1,5 @@
+---
+addReviewers: false
+addAssignees: true
+assignees:
+ - ElBe-Plaq
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..ea3679d
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,33 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+---
+version: 2
+updates:
+ - package-ecosystem: "pip"
+ directory: "/"
+ schedule:
+ interval: "daily"
+ assignees:
+ - "ElBe-Plaq"
+ labels:
+ - "dependencies"
+
+ - package-ecosystem: "cargo"
+ directory: "/"
+ schedule:
+ interval: "daily"
+ assignees:
+ - "ElBe-Plaq"
+ labels:
+ - "dependencies"
+
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "daily"
+ assignees:
+ - "ElBe-Plaq"
+ labels:
+ - "dependencies"
diff --git a/.github/errors.md b/.github/errors.md
new file mode 100644
index 0000000..f114728
--- /dev/null
+++ b/.github/errors.md
@@ -0,0 +1,3 @@
+# errors module
+
+Module for dealing with errors.
diff --git a/.github/example.png b/.github/example.png
new file mode 100644
index 0000000..92da719
Binary files /dev/null and b/.github/example.png differ
diff --git a/.github/labeler.yml b/.github/labeler.yml
new file mode 100644
index 0000000..ac92c4e
--- /dev/null
+++ b/.github/labeler.yml
@@ -0,0 +1,5 @@
+---
+example:
+ - "examples/*"
+dependencies:
+ - "dev-requirements.txt"
diff --git a/.github/mergify.yml b/.github/mergify.yml
new file mode 100644
index 0000000..cb54a5e
--- /dev/null
+++ b/.github/mergify.yml
@@ -0,0 +1,128 @@
+---
+pull_request_rules:
+ - name: Merge trusted bot updates, no conflicts are present and approved
+ conditions:
+ - or:
+ - "label~=Approved"
+ - "-#approved-reviews-by=0"
+ - "-conflict"
+ - "-draft"
+ - "-locked"
+ - "#check-failure=0"
+ - "author~=.*bot.*"
+ actions:
+ comment:
+ message: |
+ # Merging pull request
+
+ Checks:
+ | Name | Status |
+ |------|--------|
+ {% for check in check_success %}| {{check}} | :white_check_mark: |
+ {% endfor %}
+ merge:
+ commit_message_template: |
+ {{title}}
+
+ {{title}} in #{{number}} by @{{author}}, contributing to {{milestone}}
+
+ Changed files:
+ {% for file in files %}- '{{file}}'
+ {% endfor %}
+
+ Approved by: @{{ approved_reviews_by | join(', @') }}
+
+
+ {% for commit in commits %}Co-authored-by: {{commit.author}} <{{commit.email_author}}>
+ {% endfor %}
+ method: merge
+ delete_head_branch:
+ - name: Merge if approved, no conflicts are present and it's not a WIP
+ conditions:
+ - or:
+ - "-#approved-reviews-by=0"
+ - "label~=Approved"
+ - "label~=Able to merge"
+ - "-conflict"
+ - "-draft"
+ - "-locked"
+ - "#check-failure=0"
+ actions:
+ comment:
+ message: |
+ # Merging pull request
+
+ Checks:
+ | Name | Status |
+ |------|--------|
+ {% for check in check_success %}| {{check}} | :white_check_mark: |
+ {% endfor %}
+ merge:
+ commit_message_template: |
+ {{title}}
+
+ {{title}} in #{{number}} by @{{author}}, contributing to {{milestone}}
+
+ Changed files:
+ {% for file in files %}- '{{file}}'
+ {% endfor %}
+
+ Approved by: @{{ approved_reviews_by | join(', @') }}
+
+
+ {% for commit in commits %}Co-authored-by: {{commit.author}} <{{commit.email_author}}>
+ {% endfor %}
+ method: merge
+ delete_head_branch:
+ - name: Add review requested label and request review from ElBe
+ conditions:
+ - or:
+ - "#approved-reviews-by=0"
+ - "-label~=Approved"
+ - "-title~=^[WIP].*"
+ - "-label~=Declined"
+ - "-label~=Review requested"
+ - "-draft"
+ - "-locked"
+ - "-conflict"
+ actions:
+ label:
+ add:
+ - Review requested
+ request_reviews:
+ users:
+ - ElBe-Plaq
+ - name: Warn on conflicts and add label
+ conditions:
+ - conflict
+ actions:
+ comment:
+ message: "@{{author}} this pull request has one or more conflicts."
+ label:
+ add:
+ - Invalid
+ remove:
+ - Review requested
+ - name: Remove invalid label if not needed
+ conditions:
+ - -conflict
+ actions:
+ label:
+ add:
+ - Review requested
+ remove:
+ - Invalid
+ - name: Warn on failed checks
+ conditions:
+ - "-#check-failure=0"
+ actions:
+ comment:
+ message: |
+ # Checks failed
+
+ Checks:
+ | Name | Status |
+ |------|--------|
+ {% for check in check_success %}| {{check}} | :white_check_mark: |
+ {% endfor %}{% for check in check_failure %}| {{check}} | :x: |
+ {% endfor %}
diff --git a/.github/stale.yml b/.github/stale.yml
new file mode 100644
index 0000000..a4d7996
--- /dev/null
+++ b/.github/stale.yml
@@ -0,0 +1,11 @@
+---
+daysUntilStale: 60
+daysUntilClose: 7
+exemptLabels:
+ - Security
+staleLabel: stale
+markComment: >
+ This issue has been automatically marked as stale because it has not had
+ recent activity. It will be closed if no further activity occurs. Thank you
+ for your contributions.
+closeComment: false
diff --git a/.github/workflows/codecov_workflow.yml b/.github/workflows/codecov_workflow.yml
new file mode 100644
index 0000000..4a813bb
--- /dev/null
+++ b/.github/workflows/codecov_workflow.yml
@@ -0,0 +1,14 @@
+name: Codecov
+permissions: read-all
+
+on:
+ [push, pull_request]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Upload coverage reports to Codecov
+ uses: codecov/codecov-action@v3
+ env:
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml
new file mode 100644
index 0000000..c71a461
--- /dev/null
+++ b/.github/workflows/dependencies.yml
@@ -0,0 +1,46 @@
+---
+name: Dependencies
+permissions: read-all
+
+on:
+ push:
+ paths: ["dev-requirements.txt", "Cargo.toml"]
+
+ pull_request:
+ paths: ["dev-requirements.txt", "Cargo.toml"]
+
+jobs:
+ install-python-dependencies:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ python-version: ["3.8"]
+ steps:
+ - uses: actions/checkout@v4
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v4
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install dependencies from txt files
+ run: |
+ python -m pip install --upgrade pip
+ pip install -r dev-requirements.txt
+ install-rust-dependencies:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Install dependencies from Cargo.toml
+ run: cargo update
+ - name: Install dev-dependencies from Cargo.toml
+ run: cargo test --no-run
+ # ^ This is the only way to install dev-dependencies
+
+ dependency-review:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+ if: ${{ github.event_name != 'push' }}
+ - name: Dependency Review
+ if: ${{ github.event_name != 'push' }}
+ uses: actions/dependency-review-action@v3
diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml
new file mode 100644
index 0000000..34a042d
--- /dev/null
+++ b/.github/workflows/label.yml
@@ -0,0 +1,25 @@
+# This workflow will triage pull requests and apply a label based on the
+# paths that are modified in the pull request.
+#
+# To use this workflow, you will need to set up a .github/labeler.yml
+# file with configuration. For more information, see:
+# https://github.com/actions/labeler
+
+---
+name: Labeler
+permissions:
+ pull-requests: write
+
+on: [pull_request_target]
+
+jobs:
+ label:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ pull-requests: write
+
+ steps:
+ - uses: actions/labeler@v4
+ with:
+ repo-token: "${{ secrets.GITHUB_TOKEN }}"
diff --git a/.github/workflows/megalinter.yml b/.github/workflows/megalinter.yml
new file mode 100644
index 0000000..280bede
--- /dev/null
+++ b/.github/workflows/megalinter.yml
@@ -0,0 +1,38 @@
+---
+name: MegaLinter
+permissions: read-all
+
+on:
+ push:
+ pull_request:
+ branches: [main]
+
+env:
+ APPLY_FIXES: VALIDATE_ALL_CODEBASE
+ APPLY_FIXES_EVENT: all
+ APPLY_FIXES_MODE: commit
+
+concurrency:
+ group: ${{ github.ref }}-${{ github.workflow }}
+ cancel-in-progress: true
+
+jobs:
+ build:
+ name: MegaLinter
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ issues: write
+ pull-requests: write
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v4
+ with:
+ token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }}
+ fetch-depth: 0
+ - name: MegaLinter
+ id: ml
+ uses: oxsecurity/megalinter@v7
+ env:
+ VALIDATE_ALL_CODEBASE: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
new file mode 100644
index 0000000..45c562c
--- /dev/null
+++ b/.github/workflows/rust.yml
@@ -0,0 +1,18 @@
+name: Rust
+permissions: read-all
+
+on:
+ [push, pull_request]
+
+env:
+ CARGO_TERM_COLOR: always
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Build
+ run: cargo build --verbose
+ - name: Run tests
+ run: cargo test --verbose
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6985cf1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,14 @@
+# Generated by Cargo
+# will have compiled files and executables
+debug/
+target/
+
+# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
+# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
+Cargo.lock
+
+# These are backup files generated by rustfmt
+**/*.rs.bk
+
+# MSVC Windows builds of rustc generate these, which store debugging information
+*.pdb
diff --git a/.mega-linter.yml b/.mega-linter.yml
new file mode 100644
index 0000000..b10c5b8
--- /dev/null
+++ b/.mega-linter.yml
@@ -0,0 +1,16 @@
+---
+DISABLE_ERRORS_LINTERS:
+ - SPELL_CSPELL
+ - REPOSITORY_DEVSKIM # cspell:disable-line
+ - MAKEFILE_CHECKMAKE # cspell:disable-line
+ - HTML_HTMLHINT # cspell:disable-line
+ - MARKDOWN_MARKDOWN_LINK_CHECK
+ - REPOSITORY_DUSTILOCK # cspell:disable-line
+ - JAVASCRIPT_STANDARD
+ - REPOSITORY_TRUFFLEHOG # cspell:disable-line
+ - SPELL_LYCHEE
+FILTER_REGEX_EXCLUDE: .*mypy.* # cspell:disable-line
+EDITORCONFIG_EDITORCONFIG_CHECKER_FILTER_REGEX_EXCLUDE: "Docs/acknowledgements.md|src/Installer/Linux/installer.bash"
+REPORT_OUTPUT_FOLDER: none
+SHOW_ELAPSED_TIME: true
+VALIDATE_ALL_CODEBASE: false
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..6c07b01
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,38 @@
+---
+repos:
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v4.4.0
+ hooks:
+ - id: check-added-large-files
+ - id: check-executables-have-shebangs
+ - id: check-json
+ - id: check-merge-conflict
+ - id: check-shebang-scripts-are-executable
+ - id: check-toml
+ - id: check-yaml
+ - id: pretty-format-json
+ args: [--autofix]
+ - id: requirements-txt-fixer
+ - id: trailing-whitespace
+ - repo: https://github.com/jorisroovers/gitlint
+ rev: v0.19.1
+ hooks:
+ - id: gitlint
+ args: [--config=.github\.gitlint, --msg-filename]
+ - repo: https://github.com/doublify/pre-commit-rust
+ rev: v1.0
+ hooks:
+ - id: fmt
+ - id: cargo-check
+ - repo: local
+ hooks:
+ - id: clippy
+ name: Run clippy linter
+ entry: cargo clippy -- -A non_snake_case
+ language: system
+ pass_filenames: false
+ci:
+ skip:
+ - fmt
+ - cargo-check
+ - clippy
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..51ffa65
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+name = "logging-rs"
+description = "logging-rs helps you add logging to your projects using simple macros."
+version = "1.0.0"
+authors = [
+ "ElBe-Plaq "
+]
+edition = "2021"
+rust-version = "1.69"
+documentation = "https://docs.rs/logging_rs/"
+readme = ".github/README.md"
+repository = "https://github.com/ElBe-Development/logging-rs/"
+license = "MIT"
+keywords = ["log", "logger", "logging", "debug", "debugging"]
+categories = [
+ "development-tools::debugging",
+]
+publish = true
+
+[dependencies]
+# chrono = "0.4.31"
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..04e1350
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 ElBe Development
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/codecov.yml b/codecov.yml
new file mode 100644
index 0000000..b2a0e98
--- /dev/null
+++ b/codecov.yml
@@ -0,0 +1,10 @@
+coverage:
+ status:
+ project:
+ default:
+ target: 50%
+ threshold: 1%
+
+comment:
+ require_changes: true
+ require_ci_to_pass: false
diff --git a/dev-requirements.txt b/dev-requirements.txt
new file mode 100644
index 0000000..56ce91b
--- /dev/null
+++ b/dev-requirements.txt
@@ -0,0 +1 @@
+pre-commit==3.4.0; python_version>='3.8'
diff --git a/examples/main.rs b/examples/main.rs
new file mode 100644
index 0000000..cc5cb60
--- /dev/null
+++ b/examples/main.rs
@@ -0,0 +1,12 @@
+use logging_rs;
+
+fn main() {
+ let logger = logging_rs::Logger::default();
+
+ logging_rs::debug!(logger, "Debug message");
+ logging_rs::info!(logger, "Info");
+ logging_rs::warn!(logger, "Warning");
+ logging_rs::error!(logger, "Error!");
+ logging_rs::fatal!(logger, "Fatal error!");
+ logging_rs::log!(logger, "Log message");
+}
diff --git a/justfile b/justfile
new file mode 100644
index 0000000..a6550c9
--- /dev/null
+++ b/justfile
@@ -0,0 +1,25 @@
+alias b := build
+alias c := clean
+alias l := lint
+alias r := run
+alias t := test
+
+# Compiles the rust source files
+build *ARGUMENTS:
+ cargo build --release *ARGUMENTS
+
+# Removes temporary files
+clean:
+ cargo clean
+
+# Lints the rust source files
+lint *ARGUMENTS:
+ cargo check *ARGUMENTS
+
+# Compiles and executes the main.rs file
+run *ARGUMENTS:
+ cargo run *ARGUMENTS
+
+# Runs the unittests
+test *ARGUMENTS:
+ cargo test *ARGUMENTS
diff --git a/src/errors.rs b/src/errors.rs
new file mode 100644
index 0000000..3a6ef8d
--- /dev/null
+++ b/src/errors.rs
@@ -0,0 +1,159 @@
+#![doc = include_str!("../.github/errors.md")]
+// logging-rs errors
+// Version: 1.0.0
+
+// Copyright (c) 2023-present ElBe Development.
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the 'Software'),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+////////////////////////////////
+// IMPORTS AND USE STATEMENTS //
+////////////////////////////////
+
+use std::fmt;
+
+
+///////////
+// ERROR //
+///////////
+
+/// Error object.
+///
+/// Use [`Error::new()`] to create error objects instead of using this struct.
+///
+/// # Parameters
+///
+/// - `name`: The errors name.
+/// - `description`: The error description.
+/// - `exit_code`: The errors exit code.
+///
+/// # Returns
+///
+/// A new `Error` object with the specified name and description.
+///
+/// # Examples
+///
+/// ```rust
+/// # use logging_rs;
+/// logging_rs::errors::Error {
+/// name: "name".to_owned(),
+/// description: "description".to_owned(),
+/// exit_code: 1
+/// };
+/// ```
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub struct Error {
+ /// The errors name.
+ pub name: String,
+ /// The error description.
+ pub description: String,
+ /// The errors exit code.
+ pub exit_code: i32,
+}
+
+/// Display implementation for the error object.
+impl fmt::Display for Error {
+ /// Format implementation for the error object.
+ ///
+ /// # Parameters
+ ///
+ /// - `self`: The error object.
+ /// - `f`: The [`fmt::Formatter`] to use.
+ ///
+ /// # Returns
+ ///
+ /// A [`fmt::Result`] containing the formatted error message.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use logging_rs;
+ /// # let error = logging_rs::errors::Error::new("name", "description", 1);
+ /// println!("{}", error);
+ /// ```
+ ///
+ /// # See also
+ ///
+ /// - [`fmt::Display`]
+ /// - [`Error`]
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "\x1b[31;1m{}\x1b[0m: {}", self.name, self.description)
+ }
+}
+
+impl Error {
+ /// Creates a new error object.
+ ///
+ /// # Parameters
+ ///
+ /// - `name`: The errors name.
+ /// - `description`: The error description.
+ /// - `exit_code`: The errors exit code.
+ ///
+ /// # Returns
+ ///
+ /// A new `Error` object with the specified name and description.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use logging_rs;
+ /// logging_rs::errors::Error::new("name", "description", 1);
+ /// ```
+ ///
+ /// # See also
+ ///
+ /// - [`Error`]
+ pub fn new(name: &str, description: &str, exit_code: i32) -> Error {
+ return Error {
+ name: name.to_owned(),
+ description: description.to_owned(),
+ exit_code: exit_code,
+ };
+ }
+
+ /// Raises the error and exits with the specified exit code.
+ ///
+ /// # Parameters
+ ///
+ /// - `self`: The error object.
+ /// - `details`: The error details.
+ ///
+ /// # Aborts
+ ///
+ /// Exits with the specified exit code.
+ ///
+ /// # Examples
+ ///
+ /// ```should_panic
+ /// # use logging_rs;
+ /// # let error: logging_rs::errors::Error = logging_rs::errors::Error::new("name", "description", 1);
+ /// error.raise("Something went very wrong");
+ /// ```
+ ///
+ /// # See also
+ ///
+ /// - [`Error`]
+ pub fn raise(&self, details: &str) {
+ eprintln!("{}", self);
+ eprintln!("{}", details);
+
+ std::process::exit(self.exit_code);
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..ad6dcd0
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,657 @@
+#![doc = include_str!("../.github/README.md")]
+// Logging-rs.
+// Version: 1.0.0
+
+// Copyright (c) 2023-present I Language Development.
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the 'Software'),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+/////////////
+// EXPORTS //
+/////////////
+
+pub mod errors;
+
+
+/////////////
+// IMPORTS //
+/////////////
+
+use std;
+use std::io::Write;
+
+// use chrono;
+
+
+////////////////
+// LOG LEVELS //
+////////////////
+
+/// Log levels
+#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
+pub enum Level {
+ /// Debug log level. The default value
+ #[default]
+ DEBUG,
+ /// Info log level
+ INFO,
+ /// Warn log level
+ WARN,
+ /// Error log level
+ ERROR,
+ /// Fatal log level
+ FATAL,
+ /// Message log level
+ MESSAGE
+}
+
+
+//////////////////
+// HTTP METHODS //
+//////////////////
+
+// HTTP methods
+/*#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
+pub enum HTTPMethod {
+ /// GET request. The default value
+ #[default]
+ GET,
+ /// POST request
+ POST,
+ /// PUT request
+ PUT,
+ /// PATCH request
+ PATCH
+}*/
+
+
+/////////////////
+// OUTPUT TYPE //
+/////////////////
+
+/// Output types
+#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
+pub enum Output {
+ /// Stdout. The default value
+ #[default]
+ STDOUT,
+ /// Stderr
+ STDERR,
+ /// File
+ FILE {
+ /// File path
+ path: String
+ },
+ // Web request (not currently implemented)
+ /*REQUEST {
+ method: HTTPMethod,
+ url: String
+ }*/
+}
+
+
+///////////////
+// FORMATTER //
+///////////////
+
+/// Logging formatter object.
+///
+/// Use [`Formatter::new()`] to create formatter objects instead of using this struct.
+///
+/// # Parameters
+///
+/// - `color_format_string`: Format string supporting special ASCII control characters
+/// - `format_string`: Format string *NOT* supporting special ASCII control characters
+/// - `timestamp_format`: Timestamp format string in strftime format
+///
+/// # Returns
+///
+/// A new `Formatter` object with the specified format strings.
+///
+/// # Examples
+///
+/// ```rust
+/// # use logging_rs;
+/// logging_rs::Formatter {
+/// color_format_string: "format string with color support".to_owned(),
+/// format_string: "format string".to_owned(),
+/// timestamp_format: "timestamp format".to_owned()
+/// };
+/// ```
+#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
+pub struct Formatter {
+ /// Format string supporting special ASCII control characters
+ pub color_format_string: String,
+ /// Format string *NOT* supporting special ASCII control characters
+ pub format_string: String,
+ /// Timestamp format string in strftime format
+ pub timestamp_format: String,
+}
+
+impl Default for Formatter {
+ fn default() -> Formatter {
+ return Formatter::new("[{{color.bright_blue}}{{timestamp}}{{end}}] [{{level}}] {{path}}: {{message}}", "[{{timestamp}}] [{{level}}] {{path}}: {{message}}", "%Y-%m-%d %H:%M:%S");
+ }
+}
+
+impl Formatter {
+ /// Creates a new formatter object.
+ ///
+ /// # Parameters
+ ///
+ /// - `color_format_string`: Format string supporting special ASCII control characters
+ /// - `format_string`: Format string *NOT* supporting special ASCII control characters
+ /// - `timestamp_format`: Timestamp format string in strftime format
+ ///
+ /// # Returns
+ ///
+ /// A new `Formatter` object with the specified format strings.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use logging_rs;
+ /// logging_rs::Formatter::new(
+ /// "[{{color.bright_blue}}{{timestamp}}{{end}}] [{{level}}] {{path}}: {{message}}",
+ /// "[{{timestamp}}] [{{level}}] {{path}}: {{message}}",
+ /// "%Y-%m-%d %H:%M:%S"
+ /// );
+ /// ```
+ ///
+ /// # See also
+ ///
+ /// - [`Formatter`]
+ pub fn new(color_format_string: &str, format_string: &str, timestamp_format: &str) -> Formatter {
+ Formatter {
+ color_format_string: color_format_string.to_owned(),
+ format_string: format_string.to_owned(),
+ timestamp_format: timestamp_format.to_owned()
+ }
+ }
+
+ /// Formats the given message.
+ ///
+ /// # Parameters
+ ///
+ /// - `self`: The formatter object
+ /// - `output`: The [`Output`] to write to
+ /// - `level`: The log [`Level`] to use for formatting
+ /// - `message`: The message to log
+ /// - `arguments`: A vector of additional formatting arguments
+ ///
+ /// # Returns
+ ///
+ /// A `String` containing the formatted message.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use logging_rs;
+ /// # let formatter: logging_rs::Formatter = logging_rs::Formatter::default();
+ /// formatter.format(
+ /// logging_rs::Output::default(),
+ /// logging_rs::Level::default(),
+ /// "Some message with an {{argument}}",
+ /// vec![("argument", "replaced value")]
+ /// );
+ /// ```
+ ///
+ /// # See also
+ ///
+ /// - [`Formatter`]
+ /// - [`Output`]
+ /// - [`Level`]
+ pub fn format<'a>(&self, output: Output, level: Level, message: &'a str, mut arguments: Vec<(&str, &'a str)>) -> String {
+ // TODO (ElBe): Make timestamps work. None of chrono, time or humantime have the things I want
+ let timestamp: &str = "TIMESTAMP";
+
+ // let time = chrono::Utc::now();
+ //let _timestamp = time.format("%Y-%m-%d %H:%M:%S").to_string(); //chrono::format::DelayedFormat>
+ //let parsed = chrono::NaiveDateTime::parse_from_str(&_timestamp.to_string(), "%Y-%m-%d %H:%M:%S").expect("Bad");
+
+ //let borrowed = &_timestamp;
+
+ //println!("{}", _timestamp);
+ //println!("{}", parsed.to_string().as_str());
+
+ // arguments.push(("timestamp", &time.format("%Y-%m-%d %H:%M:%S").to_string()));
+
+ let mut colors: Vec<(&str, &str)> = vec![
+ // Formatting codes
+ ("end", "\x1b[0m"),
+ ("bold", "\x1b[1m"),
+ ("italic", "\x1b[3m"),
+ ("underline", "\x1b[4m"),
+ ("overline", "\x1b[53m"),
+
+ // Foreground colors
+ ("color.black", "\x1b[30m"),
+ ("color.red", "\x1b[31m"),
+ ("color.green", "\x1b[32m"),
+ ("color.yellow", "\x1b[33m"),
+ ("color.blue", "\x1b[34m"),
+ ("color.magenta", "\x1b[35m"),
+ ("color.cyan", "\x1b[36m"),
+ ("color.white", "\x1b[37m"),
+
+ // Bright foreground colors
+ ("color.bright_black", "\x1b[90m"),
+ ("color.bright_red", "\x1b[91m"),
+ ("color.bright_green", "\x1b[92m"),
+ ("color.bright_yellow", "\x1b[93m"),
+ ("color.bright_blue", "\x1b[94m"),
+ ("color.bright_magenta", "\x1b[95m"),
+ ("color.bright_cyan", "\x1b[96m"),
+ ("color.bright_white", "\x1b[97m"),
+
+ // Background colors
+ ("back.black", "\x1b[40m"),
+ ("back.red", "\x1b[41m"),
+ ("back.green", "\x1b[42m"),
+ ("back.yellow", "\x1b[43m"),
+ ("back.blue", "\x1b[44m"),
+ ("back.magenta", "\x1b[45m"),
+ ("back.cyan", "\x1b[46m"),
+ ("back.white", "\x1b[47m"),
+
+ // Bright background colors
+ ("back.bright_black", "\x1b[100m"),
+ ("back.bright_red", "\x1b[101m"),
+ ("back.bright_green", "\x1b[102m"),
+ ("back.bright_yellow", "\x1b[103m"),
+ ("back.bright_blue", "\x1b[104m"),
+ ("back.bright_magenta", "\x1b[105m"),
+ ("back.bright_cyan", "\x1b[106m"),
+ ("back.bright_white", "\x1b[107m"),
+ ];
+
+ let level_string: (&str, &str) = ("level", match level {
+ Level::DEBUG => "DEBUG",
+ Level::INFO => "INFO",
+ Level::WARN => "WARNING",
+ Level::ERROR => "ERROR",
+ Level::FATAL => "FATAL",
+ Level::MESSAGE => "MESSAGE"
+ });
+ let colored_level_string: (&str, &str) = ("level", match level {
+ Level::DEBUG => "DEBUG",
+ Level::INFO => "{{color.blue}}INFO{{end}}",
+ Level::WARN => "{{color.yellow}}WARNING{{end}}",
+ Level::ERROR => "{{color.red}}ERROR{{end}}",
+ Level::FATAL => "{{color.red}}FATAL{{end}}",
+ Level::MESSAGE => "{{color.blue}}MESSAGE{{end}}"
+ });
+
+ arguments.push(("message", message));
+ arguments.push(("timestamp", timestamp));
+ //arguments.push(("timestamp", chrono::Utc::now().format("%Y-%m-%d %H:%M:%S").to_string().to_owned().as_str()));
+
+ let mut result: String = match output {
+ Output::STDOUT | Output::STDERR => {
+ arguments.push(colored_level_string);
+ self.color_format_string.to_owned()
+ },
+ _ => {
+ arguments.push(level_string);
+ self.format_string.to_owned()
+ }
+ };
+
+ arguments.append(&mut colors);
+
+ for (key, value) in arguments {
+ result = result.replace(("{{".to_owned() + key + "}}").as_str(), value);
+ }
+
+ return result.clone();
+ }
+}
+
+
+///////////////////
+// LOGGER STRUCT //
+///////////////////
+
+/// Logger object.
+///
+/// Use [`Logger::new()`] to create logger objects instead of using this struct.
+///
+/// # Parameters
+///
+/// - `formatter`: The [`Formatter`] to use for formatting messages
+/// - `writable_list`: A vector of [`Output`]s to write to
+///
+/// # Returns
+///
+/// A new `Logger` object with the specified formatter and writables.
+///
+/// # Examples
+///
+/// ```rust
+/// # use logging_rs;
+/// logging_rs::Logger {
+/// formatter: logging_rs::Formatter::default(),
+/// writable_list: vec![logging_rs::Output::default()]
+/// };
+/// ```
+#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
+pub struct Logger {
+ pub formatter: Formatter,
+ pub writable_list: Vec