diff --git a/.cargo/config.toml b/.cargo/config.toml
new file mode 100644
index 0000000..3f72aba
--- /dev/null
+++ b/.cargo/config.toml
@@ -0,0 +1,2 @@
+[alias]
+xtask = "run --package xtask --bin xtask --"
\ No newline at end of file
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
deleted file mode 100644
index 023074d..0000000
--- a/.github/CONTRIBUTING.md
+++ /dev/null
@@ -1,67 +0,0 @@
-# Contributing
-
-Thank you so much for wanting to contribute to Common (CMN)!
-There are a couple ways to help out.
-
-## Evangelize
-
-Just tell people about Common (CMN). We believe that a bigger,
-more involved community makes for a better framework, and that better
-frameworks make the world a better place. We can always use more
-feedback.
-
-## How to Contribute
-
-Here are guides for submitting issues and pull requests.
-
-### Bug Reports
-
-If you encounter a bug that hasn't already been filed, please file a
-bug report. Let us know of things we should fix, things we should add,
-questions, etc.
-
-Warning us of a bug is possibly the single most valuable contribution
-you can make to Common (CMN).
-
-- Head
- [here](https://github.com/sebastienrousseau/mini-functions/issues/new)
- to submit a new issue.
-- Include a descriptive title that is straight to the point.
-- Write a detailed description on what the issue is all about.
-- Wait for someone to get to the issue and add labels.
-- The issue will be fixed soon!
-
-### Code Contributions
-
-Contributing code is one of the more difficult ways to contribute to the
-Mini Functions.
-
-#### Feature Requests
-
-Filing feature requests is one of the most popular ways to contribute to
-Common (CMN).
-
-Is there some feature request that you'd like to code up yourself? Is
-there a feature you asked for yourself that you'd like to code?
-
-Here's how to contribute code for a new feature to Common (CMN).
-Pull Requests allow you to share your own code with us, and we can merge
-it into the main repo.
-
-#### Adding Code
-
-- Fork the repo.
-- Clone the Common (CMN) repo by running:
- `git clone https://github.com/sebastienrousseau/mini-functions.git`
-- Edit files in the `src/` folder. The `src/` folder contains the source
- code for Common (CMN).
-
-#### Fixing an Issue
-
-Have you found a solution to an issue? Here is how you can submit your
-code to Common (CMN).
-
-- Fork the repo, and refer above for how to change up code.
-- Head to your local fork of the repo and click the "New Pull Request" button.
-- Include a title that is straight to the point.
-- Wait for someone to review the pull request, and then merge yours!
diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml
new file mode 100644
index 0000000..efbedcb
--- /dev/null
+++ b/.github/workflows/audit.yml
@@ -0,0 +1,23 @@
+name: ๐งช Audit
+
+on:
+ push:
+ branches:
+ - feat/cmn
+ pull_request:
+ branches:
+ - feat/cmn
+ release:
+ types: [created]
+
+jobs:
+ dependencies:
+ name: Audit dependencies
+ runs-on: ubuntu-latest
+ steps:
+ - uses: hecrj/setup-rust-action@v1
+ - name: Install cargo-audit
+ run: cargo install cargo-audit
+ - uses: actions/checkout@master
+ - name: Audit dependencies
+ run: cargo audit
diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
new file mode 100644
index 0000000..263b9a2
--- /dev/null
+++ b/.github/workflows/check.yml
@@ -0,0 +1,23 @@
+name: ๐งช Check
+
+on:
+ push:
+ branches:
+ - feat/cmn
+ pull_request:
+ branches:
+ - feat/cmn
+ release:
+ types: [created]
+
+jobs:
+ all:
+ name: Check
+ runs-on: ubuntu-latest
+ steps:
+ - uses: hecrj/setup-rust-action@v1
+ with:
+ components: clippy
+ - uses: actions/checkout@master
+ - name: Check lints
+ run: cargo check --all-targets --workspace --all-features
diff --git a/.github/workflows/document.yml b/.github/workflows/document.yml
new file mode 100644
index 0000000..e31c03c
--- /dev/null
+++ b/.github/workflows/document.yml
@@ -0,0 +1,57 @@
+name: ๐งช Document
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ branches:
+ - main
+
+jobs:
+ all:
+ name: Document
+ if: github.ref == 'refs/heads/main' && github.event_name == 'push'
+ runs-on: ubuntu-latest
+ concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ steps:
+ - uses: hecrj/setup-rust-action@v1
+ with:
+ rust-version: nightly
+
+ - uses: actions/checkout@v3
+
+ - name: Update libssl
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y libssl1.1
+
+ - name: Generate documentation for all features and publish it
+ run: |
+ RUSTDOCFLAGS="--cfg docsrs" \
+ cargo doc --no-deps --all-features --workspace
+ # Write index.html with redirect
+ echo '
' > ./target/doc/index.html
+
+ - name: Deploy
+ uses: actions/upload-artifact@v3
+ with:
+ name: documentation
+ path: target/doc
+ if-no-files-found: error
+ retention-days: 1
+
+ - name: Write CNAME file
+ run: echo 'doc.cmnlib.one' > ./target/doc/CNAME
+
+ - name: Deploy to GitHub Pages
+ uses: peaceiris/actions-gh-pages@v3.9.3
+ with:
+ cname: true
+ commit_message: Deploy documentation at ${{ github.sha }}
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_branch: gh-pages
+ publish_dir: ./target/doc
+ user_email: actions@users.noreply.github.com
+ user_name: github-actions
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 0000000..45ceff6
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,23 @@
+name: ๐งช Lint
+
+on:
+ push:
+ branches:
+ - feat/cmn
+ pull_request:
+ branches:
+ - feat/cmn
+ release:
+ types: [created]
+
+jobs:
+ all:
+ name: Lint
+ runs-on: ubuntu-latest
+ steps:
+ - uses: hecrj/setup-rust-action@v1
+ with:
+ components: clippy
+ - uses: actions/checkout@master
+ - name: Check lints
+ run: cargo clippy --workspace --all-features --all-targets --no-deps -- -D warnings
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..d9dd1a3
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,364 @@
+name: ๐งช Release
+
+on: [push, pull_request]
+
+jobs:
+ # Build the project for all the targets and generate artifacts.
+ build:
+ # This job builds the project for all the targets and generates a
+ # release artifact that contains the binaries for all the targets.
+ name: โฏ Build ๐
+
+ # Only run this job on the main branch when a commit is pushed.
+ if: github.ref == 'refs/heads/main' && github.event_name == 'push'
+
+ # Set up the job environment variables.
+ env:
+ BUILD_ID: ${{ github.run_id }}
+ CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_API_TOKEN }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ OS: ${{ matrix.os }}
+ TARGET: ${{ matrix.target }}
+
+ strategy:
+ fail-fast: false
+ matrix:
+ target:
+ # List of targets:
+ # https://doc.rust-lang.org/nightly/rustc/platform-support.html
+
+ # Tier 1 platforms ๐
+ - aarch64-unknown-linux-gnu # 64-bit Linux systems on ARM architecture
+ - i686-pc-windows-gnu # 32-bit Windows (i686-pc-windows-gnu)
+ - i686-pc-windows-msvc # 32-bit Windows (i686-pc-windows-msvc)
+ - i686-unknown-linux-gnu # 32-bit Linux (kernel 3.2+, glibc 2.17+)
+ - x86_64-apple-darwin # 64-bit macOS (10.7 Lion or later)
+ - x86_64-pc-windows-gnu # 64-bit Windows (x86_64-pc-windows-gnu)
+ - x86_64-pc-windows-msvc # 64-bit Windows (x86_64-pc-windows-msvc)
+ - x86_64-unknown-linux-gnu # 64-bit Linux (kernel 2.6.32+, glibc 2.11+)
+
+ # Tier 2 platforms ๐ฅ
+ - aarch64-apple-darwin # 64-bit macOS on Apple Silicon
+ - aarch64-pc-windows-msvc # 64-bit Windows (aarch64-pc-windows-msvc)
+ - aarch64-unknown-linux-musl # 64-bit Linux systems on ARM architecture
+ - arm-unknown-linux-gnueabi # ARMv6 Linux (kernel 3.2, glibc 2.17)
+ - arm-unknown-linux-gnueabihf # ARMv7 Linux, hardfloat (kernel 3.2, glibc 2.17)
+ - armv7-unknown-linux-gnueabihf # ARMv7 Linux, hardfloat (kernel 3.2, glibc 2.17)
+ - mips-unknown-linux-gnu # MIPS Linux (kernel 3.2, glibc 2.17)
+ - mips64-unknown-linux-gnuabi64 # MIPS64 Linux (kernel 3.2, glibc 2.17)
+ - mips64el-unknown-linux-gnuabi64 # MIPS64el Linux (kernel 3.2, glibc 2.17)
+ - mipsel-unknown-linux-gnu # MIPSel Linux (kernel 3.2, glibc 2.17)
+ - powerpc-unknown-linux-gnu # PowerPC Linux (kernel 3.2, glibc 2.17)
+ - powerpc64-unknown-linux-gnu # PowerPC64 Linux (kernel 3.2, glibc 2.17)
+ - powerpc64le-unknown-linux-gnu # PowerPC64le Linux (kernel 3.2, glibc 2.17)
+ - riscv64gc-unknown-linux-gnu # RISC-V Linux (kernel 3.2, glibc 2.17)
+ - s390x-unknown-linux-gnu # s390x Linux (kernel 3.2, glibc 2.17)
+ - x86_64-unknown-freebsd # 64-bit FreeBSD on x86-64
+ # # - x86_64-unknown-illumos # 64-bit Illumos on x86-64
+ - x86_64-unknown-linux-musl # 64-bit Linux (kernel 2.6.32+, musl libc)
+ - x86_64-unknown-netbsd # 64-bit NetBSD on x86-64
+
+ include:
+ # Tier 1 platforms ๐
+ - target: aarch64-unknown-linux-gnu
+ os: ubuntu-latest
+ cross: true
+ - target: i686-pc-windows-gnu
+ os: ubuntu-latest
+ cross: true
+ - target: i686-pc-windows-msvc
+ os: windows-latest
+ cross: true
+ - target: i686-unknown-linux-gnu
+ os: ubuntu-latest
+ cross: true
+ - target: x86_64-apple-darwin
+ os: macos-latest
+ cross: true
+ - target: x86_64-pc-windows-gnu
+ os: ubuntu-latest
+ cross: true
+ - target: x86_64-pc-windows-msvc
+ os: windows-latest
+ cross: true
+ - target: x86_64-unknown-linux-gnu
+ os: ubuntu-latest
+ cross: true
+
+ # Tier 2 platforms ๐ฅ
+ - target: aarch64-apple-darwin
+ os: macos-latest
+ cross: true
+ - target: aarch64-pc-windows-msvc
+ os: windows-latest
+ cross: true
+ - target: aarch64-unknown-linux-musl
+ os: ubuntu-latest
+ cross: true
+ - target: arm-unknown-linux-gnueabi
+ os: ubuntu-latest
+ cross: true
+ - target: arm-unknown-linux-gnueabihf
+ os: ubuntu-latest
+ cross: true
+ - target: armv7-unknown-linux-gnueabihf
+ os: ubuntu-latest
+ cross: true
+ - target: mips-unknown-linux-gnu
+ os: ubuntu-latest
+ cross: true
+ - target: mips64-unknown-linux-gnuabi64
+ os: ubuntu-latest
+ cross: true
+ - target: mips64el-unknown-linux-gnuabi64
+ os: ubuntu-latest
+ cross: true
+ - target: mipsel-unknown-linux-gnu
+ os: ubuntu-latest
+ cross: true
+ - target: powerpc-unknown-linux-gnu
+ os: ubuntu-latest
+ cross: true
+ - target: powerpc64-unknown-linux-gnu
+ os: ubuntu-latest
+ cross: true
+ - target: powerpc64le-unknown-linux-gnu
+ os: ubuntu-latest
+ cross: true
+ - target: riscv64gc-unknown-linux-gnu
+ os: ubuntu-latest
+ cross: true
+ - target: s390x-unknown-linux-gnu
+ os: ubuntu-latest
+ cross: true
+ - target: x86_64-unknown-freebsd
+ os: ubuntu-latest
+ cross: true
+ # - target: x86_64-unknown-illumos
+ # os: ubuntu-latest
+ # cross: true
+ - target: x86_64-unknown-linux-musl
+ os: ubuntu-latest
+ cross: true
+ - target: x86_64-unknown-netbsd
+ os: ubuntu-latest
+ cross: true
+
+ runs-on: ${{ matrix.os }}
+
+ steps:
+ # Check out the repository code.
+ - name: Checkout sources
+ id: checkout
+ uses: actions/checkout@v3
+
+ # Install the stable Rust toolchain.
+ - name: Install stable toolchain
+ id: install-toolchain
+ uses: actions-rs/toolchain@v1
+ with:
+ toolchain: stable
+ override: true
+
+ # Install the targets for the cross-compilation toolchain
+ - name: Install target
+ id: install-target
+ run: rustup target add ${{ env.TARGET }}
+
+ - name: Install Cross and clean artifacts
+ run: |
+ # Install cross
+ cargo install cross
+
+ # Clean the build artifacts
+ cargo clean --verbose
+ shell: bash
+
+ # Cache dependencies to speed up subsequent builds.
+ - name: Cache dependencies
+ id: cache-dependencies
+ uses: actions/cache@v3
+ with:
+ path: |
+ ~/.cargo/bin/
+ ~/.cargo/registry/index/
+ ~/.cargo/registry/cache/
+ ~/.cargo/git/db/
+ target/
+ key: release-${{ runner.os }}-cargo-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }}
+ restore-keys: ${{ runner.os }}-cargo-
+
+ # Build the targets
+ - name: Build targets
+ id: build-targets
+ uses: actions-rs/cargo@v1
+ with:
+ use-cross: true
+ command: build
+ args: --verbose --workspace --release --target ${{ env.TARGET }}
+
+ # Package the binary for each target
+ - name: Package the binary
+ id: package-binary
+ run: |
+ if [[ ! -d "target/package" ]]; then
+ mkdir -p target/package
+ fi
+ tar czf target/package/${{ env.TARGET }}.tar.gz -C target/${{ env.TARGET }}/release .
+ echo "${{ env.TARGET }}.tar.gz=target/package/${{ env.TARGET }}.tar.gz" >> $GITHUB_ENV
+ shell: bash
+
+ # Upload the binary for each target
+ - name: Upload the binary
+ id: upload-binary
+ uses: actions/upload-artifact@v3
+ with:
+ name: ${{ env.TARGET }}.tar.gz
+ path: target/package/${{ env.TARGET }}.tar.gz
+
+ # Release the binary to GitHub Releases
+ release:
+ name: โฏ Release ๐
+ if: github.ref == 'refs/heads/main' && github.event_name == 'push'
+ needs: [build]
+ runs-on: ubuntu-latest
+ steps:
+ # Check out the repository code
+ - name: Checkout sources
+ uses: actions/checkout@v3
+
+ # Install the stable Rust toolchain
+ - name: Install stable toolchain
+ uses: actions-rs/toolchain@v1.0.6
+ with:
+ toolchain: stable
+ override: true
+
+ # Update the version number based on the Cargo.toml file
+ - name: Update version number
+ run: |
+ NEW_VERSION=$(grep version Cargo.toml | sed -n 2p | cut -d '"' -f 2)
+ echo "VERSION=$NEW_VERSION" >> "$GITHUB_ENV"
+ shell: /bin/bash -e {0}
+
+ # Cache dependencies to speed up subsequent builds
+ - name: Cache dependencies
+ uses: actions/cache@v3
+ with:
+ path: ~/.cargo
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
+ restore-keys: ${{ runner.os }}-cargo-
+
+ # Download the artifacts from the build job
+ - name: Download artifacts
+ run: |
+ for target in ${{ env.TARGET }}; do
+ echo "Downloading $target artifact"
+ name="${target}.tar.gz"
+ echo "Artifact name: $name"
+ curl -sSL -H "Authorization: token ${GITHUB_TOKEN}" -H "Accept: application/vnd.github.v3+json" -L "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/actions/runs/${BUILD_ID}/artifacts/${name}" -o "target/package/${name}"
+ done
+
+ env:
+ VERSION: ${{ env.VERSION }}
+ TARGET: ${{ env.TARGET }}
+ OS: ${{ env.OS }}
+
+ # Generate the changelog based on the git log
+ - name: Generate Changelog
+ id: generate-changelog
+ env:
+ BUILD_ID: ${{ github.run_id }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ RELEASE_URL: https://github.com/sebastienrousseau/cmn/releases
+ TARGET: ${{ env.TARGET }}
+
+ run: |
+ if [[ ! -f CHANGELOG.md ]]; then
+ # Set path to changelog file
+ changelog_file="${{ github.workspace }}/CHANGELOG.md"
+
+ # Get version from Cargo.toml
+ version=$(grep version Cargo.toml | sed -n 2p | cut -d '"' -f 2)
+
+ # Append version information to changelog
+ echo "## Release v${version} - $(date +'%Y-%m-%d')" >> "${changelog_file}"
+
+ # Copy content of template file to changelog
+ cat TEMPLATE.md >> "${changelog_file}"
+
+ # Append git log to changelog
+ echo "$(git log --pretty=format:'%s' --reverse HEAD)" >> "${changelog_file}"
+
+ # Append empty line to changelog
+ echo "" >> "${changelog_file}"
+
+ fi
+ shell: bash
+
+ # Create the release on GitHub releases
+ - name: Create Release
+ id: create-release
+ uses: actions/create-release@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ VERSION: ${{ env.VERSION }}
+ with:
+ tag_name: v${{ env.VERSION }}
+ release_name: Common (CMN) ๐ฆ v${{ env.VERSION }}
+ body_path: ${{ github.workspace }}/CHANGELOG.md
+ draft: true
+ prerelease: false
+
+ # Publish the release to Crates.io automatically
+ crate:
+ name: โฏ Crate.io ๐ฆ
+ if: github.ref == 'refs/heads/main' && github.event_name == 'push'
+ needs: [release]
+ runs-on: ubuntu-latest
+
+ steps:
+ # Check out the repository code
+ - name: Checkout
+ uses: actions/checkout@v3
+
+ # Install the stable Rust toolchain
+ - name: Install stable toolchain
+ id: install-toolchain
+ uses: actions-rs/toolchain@v1.0.6
+ with:
+ toolchain: stable
+ override: true
+
+ # Cache dependencies to speed up subsequent builds
+ - name: Cache dependencies
+ id: cache-dependencies
+ uses: actions/cache@v3
+ with:
+ path: /home/runner/.cargo/registry/index/
+ key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
+ restore-keys: ${{ runner.os }}-cargo-index-
+
+ # Update the version number based on the Cargo.toml file
+ - name: Update version number
+ id: update-version
+ run: |
+ NEW_VERSION=$(grep version Cargo.toml | sed -n 2p | cut -d '"' -f 2)
+ echo "VERSION=$NEW_VERSION" >> "$GITHUB_ENV"
+ shell: /bin/bash -e {0}
+
+ # Log in to crates.io
+ - name: Log in to crates.io
+ id: login-crate-io
+ run: cargo login ${{ secrets.CARGO_API_TOKEN }}
+
+ # Publish the Rust library to Crate.io
+ - name: Publish Library to Crate.io
+ id: publish-library
+ uses: actions-rs/cargo@v1.0.1
+ env:
+ CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_API_TOKEN }}
+ with:
+ command: publish
+ args: "--no-verify --allow-dirty"
+ use-cross: false
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
deleted file mode 100644
index 157300f..0000000
--- a/.github/workflows/rust.yml
+++ /dev/null
@@ -1,221 +0,0 @@
-name: โฏ CMN Release
-
-on: [push]
-
-env:
- CARGO_TERM_COLOR: always
-
-jobs:
- targets:
- name: mf_${{ matrix.target }}
- runs-on: ${{ matrix.os }}
- strategy:
- fail-fast: false
- matrix:
- target:
- # List of targets: https://doc.rust-lang.org/nightly/rustc/platform-support.html
-
- # Linux targets ๐ง
- - aarch64-unknown-linux-gnu # 64-bit Linux systems on ARM architecture โ
Tested
- - aarch64-unknown-linux-musl # 64-bit Linux systems on ARM architecture โ
Tested
- - arm-unknown-linux-gnueabi # ARMv6 Linux (kernel 3.2, glibc 2.17) โ
Tested
- - armv7-unknown-linux-gnueabihf # ARMv7 Linux, hardfloat (kernel 3.2, glibc 2.17) โ
Tested
- - i686-unknown-linux-gnu # 32-bit Linux (kernel 3.2+, glibc 2.17+) โ
Tested
- - i686-unknown-linux-musl # 32-bit Linux (kernel 3.2+, musl libc) โ
Tested
- # - mips-unknown-linux-gnu # MIPS Linux (kernel 2.6.32+, glibc 2.11+) โ Tested
- # - mips-unknown-linux-musl # MIPS Linux (kernel 2.6.32+, musl libc) โ Tested
- # - mips64-unknown-linux-gnuabi64 # MIPS64 Linux (kernel 2.6.32+, glibc 2.11+) โ Tested
- # - mips64el-unknown-linux-gnuabi64 # MIPS64el Linux (kernel 2.6.32+, glibc 2.11+) โ Tested
- # - mipsel-unknown-linux-gnu # MIPSel Linux (kernel 2.6.32+, glibc 2.11+) โ Tested
- # - powerpc64le-unknown-linux-gnu # 64-bit PowerPC Linux (kernel 2.6.32+, glibc 2.11+)โ Tested
- - x86_64-unknown-linux-gnu # 64-bit Linux (kernel 2.6.32+, glibc 2.11+) โ
Tested
- - x86_64-unknown-linux-musl # 64-bit Linux (kernel 2.6.32+, musl libc) โ
Tested
-
- # macOS targets ๐
- - x86_64-apple-darwin # 64-bit macOS (10.7 Lion or later) โ
Tested
-
- # Windows targets ๐ช
- # - i686-pc-windows-msvc # 32-bit Windows โ Tested
- # - x86_64-pc-windows-msvc # 64-bit Windows โ Tested
-
- include:
- # Linux targets ๐ง
- - target: aarch64-unknown-linux-gnu # 64-bit Linux systems on ARM architecture
- os: ubuntu-latest
- cross: true
- - target: aarch64-unknown-linux-musl # 64-bit Linux systems on ARM architecture
- os: ubuntu-latest
- cross: true
- - target: arm-unknown-linux-gnueabi # ARMv6 Linux (kernel 3.2, glibc 2.17)
- os: ubuntu-latest
- cross: true
- - target: armv7-unknown-linux-gnueabihf # ARMv7 Linux, hardfloat (kernel 3.2, glibc 2.17)
- os: ubuntu-latest
- cross: true
- - target: i686-unknown-linux-gnu # 32-bit Linux (kernel 3.2+, glibc 2.17+)
- os: ubuntu-latest
- cross: true
- - target: i686-unknown-linux-musl # 32-bit Linux (kernel 3.2+, musl libc)
- os: ubuntu-latest
- cross: true
- # - target: mips-unknown-linux-gnu # MIPS Linux (kernel 2.6.32+, glibc 2.11+)
- # os: ubuntu-latest
- # cross: true
- # - target: mips-unknown-linux-musl # MIPS Linux (kernel 2.6.32+, musl libc)
- # os: ubuntu-latest
- # cross: true
- # - target: mips64-unknown-linux-gnuabi64 # MIPS64 Linux (kernel 2.6.32+, glibc 2.11+)
- # os: ubuntu-latest
- # cross: true
- # - target: mips64el-unknown-linux-gnuabi64 # MIPS64el Linux (kernel 2.6.32+, glibc 2.11+)
- # os: ubuntu-latest
- # cross: true
- # - target: mipsel-unknown-linux-gnu # MIPSel Linux (kernel 2.6.32+, glibc 2.11+)
- # os: ubuntu-latest
- # cross: true
- # - target: powerpc64le-unknown-linux-gnu # 64-bit PowerPC Linux (kernel 2.6.32+, glibc 2.11+)
- # os: ubuntu-latest
- # cross: true
- - target: x86_64-unknown-linux-gnu # 64-bit Linux (kernel 2.6.32+, glibc 2.11+)
- os: ubuntu-latest
- cross: true
- - target: x86_64-unknown-linux-musl # 64-bit Linux (kernel 2.6.32+, musl libc)
- os: ubuntu-latest
- cross: true
-
- # macOS targets ๐
- - target: x86_64-apple-darwin # 64-bit macOS (10.7 Lion or later)
- os: macos-latest
- cross: true
-
- # Windows targets ๐ช
- # - target: i686-pc-windows-msvc # 32-bit Windows
- # os: windows-latest
- # cross: true
- # - target: x86_64-pc-windows-msvc # 64-bit Windows
- # os: windows-latest
- # cross: true
-
- max-parallel: 2
-
- steps:
- - name: Checkout repository ๐๏ธ
- id: checkout-repository
- uses: actions/checkout@v3
- with: { submodules: true }
-
- - name: Installing Rust ๐ฆ
- id: install-rust
- run: |
- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
- shell: /bin/bash -e {0}
-
- - name: Update version number ๐งฎ
- id: update-version
- if: github.ref == 'refs/heads/main' && !github.event.check_run.conclusion
- run: |
- NEW_VERSION=$(grep version Cargo.toml | sed -n 2p | cut -d '"' -f 2)
- echo "VERSION=$NEW_VERSION" >> $GITHUB_ENV
- shell: /bin/bash -e {0}
-
- - name: Install Cross ๐ฆ
- id: install-cross
- run: |
- # Install cross
- cargo install cross
-
- # Clean the build artifacts
- cargo clean --verbose
- shell: /bin/bash -e {0}
-
- - name: Build targets ๐
- id: build-targets
- uses: actions-rs/cargo@v1
- with:
- use-cross: true
- command: build
- args: --verbose --release --target ${{ matrix.target }}
-
- - name: Run Cargo Format ๐ฆ
- id: run-check-format
- run: |
- cargo check --all --all-features --release --verbose
-
- - name: Run Clippy ๐ฆ
- id: run-check-clippy
- run: |
- cargo clippy --all-targets --all-features --release -- -D warnings
-
- - name: Run Cargo Doc ๐ฆ
- id: run-check-doc
- if: github.ref == 'refs/heads/main'
- run: |
- cargo doc --color always --no-deps --all-features --release --verbose
-
- - name: Run Cargo Test ๐ฆ
- id: run-check-test
- if: github.ref == 'refs/heads/main'
- run: |
- cargo test --all-targets --workspace --all-features
-
- - name: Run Cargo Code Coverage ๐ฆ
- id: run-check-code-coverage
- if: github.ref == 'refs/heads/main'
- run: |
- # Install tarpaulin
- cargo install cargo-tarpaulin
-
- # Run tarpaulin and generate the code coverage report
- cargo tarpaulin --all --all-features --workspace --out Xml
-
- - name: Upload to codecov.io ๐
- id: upload-codecov
- if: github.ref == 'refs/heads/main'
- uses: codecov/codecov-action@v3
- with:
- token: ${{ secrets.CODECOV_TOKEN }}
- fail_ci_if_error: false
- verbose: false
-
- - name: Package the binary ๐ฆ
- id: package-binary
- if: github.ref == 'refs/heads/main'
- run: |
- mkdir -p target/package
- tar czf target/package/${{ matrix.target }}.tar.gz -C target/${{ matrix.target }}/release .
-
- - name: Deploy binary ๐
- id: deploy-binary
- if: github.ref == 'refs/heads/main'
- uses: actions/upload-artifact@v3
- with:
- name: ${{ matrix.target }}.tar.gz
- path: target/package/${{ matrix.target }}.tar.gz
-
- - name: Generate Changelog ๐
- id: generate-changelog
- if: github.ref == 'refs/heads/main'
- run: |
- # Append version information to CHANGELOG.md
- echo "## [${{ env.VERSION }}] - $(date +'%Y-%m-%d')" >> ${{ github.workspace }}/CHANGELOG.md
- # Copy content of template file to CHANGELOG.md
- cat README.md > ${{ github.workspace }}/CHANGELOG.md
- # Append git log to CHANGELOG.md
- echo "$(git log --pretty=format:'%s' --reverse $(git describe --tags --abbrev=0)..HEAD)" >> ${{ github.workspace }}/CHANGELOG.md
- # Append empty line to CHANGELOG.md
- echo "" >> ${{ github.workspace }}/CHANGELOG.md
- # Append empty line to CHANGELOG.md
- echo "" >> ${{ github.workspace }}/CHANGELOG.md
-
- - name: Create Release ๐
- id: create_release
- if: github.ref == 'refs/heads/main'
- uses: actions/create-release@v1
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- tag_name: v${{ env.VERSION }}
- release_name: Common (CMN) ๐ฆ v${{ env.VERSION }}
- body_path: ${{ github.workspace }}/CHANGELOG.md
- draft: true
- prerelease: false
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000..8a52e9f
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,69 @@
+name: ๐งช Test
+
+on: [pull_request, push]
+jobs:
+ test-lib:
+ name: Test library
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ os: [ubuntu-latest]
+ toolchain: [stable, nightly]
+ continue-on-error: true
+
+ steps:
+ # Checkout the repository
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ # Setup Rust
+ - name: Setup Rust
+ run: |
+ rustup toolchain add ${{ matrix.toolchain }} --component llvm-tools-preview
+ rustup override set ${{ matrix.toolchain }}
+
+ # Configure cache
+ - name: Configure cache
+ uses: actions/cache@v3
+ with:
+ path: |
+ ~/.cargo/bin/
+ ~/.cargo/registry/index/
+ ~/.cargo/registry/cache/
+ ~/.cargo/git/db/
+ target/
+ key: test-${{ runner.os }}-cargo-${{ matrix.toolchain }}-${{ hashFiles('**/Cargo.lock') }}
+
+ # Run tests with all features
+ - name: Run tests with all features
+ id: run-tests-all-features
+ run: cargo test --verbose --workspace --all-features
+
+ # Install grcov
+ - name: Install grcov
+ # Only run this job on the main branch when a commit is pushed.
+ if: github.ref == 'refs/heads/main' && github.event_name == 'push'
+ id: install-grcov
+ run: |
+ mkdir -p "${HOME}/.local/bin"
+ curl -sL https://github.com/mozilla/grcov/releases/download/v0.8.18/grcov-x86_64-unknown-linux-gnu.tar.bz2 | tar jxf - -C "${HOME}/.local/bin"
+ echo "$HOME/.local/bin" >> $GITHUB_PATH
+
+ # Use grcov to generate a coverage report
+ - name: Generate coverage report
+ # Only run this job on the main branch when a commit is pushed.
+ if: github.ref == 'refs/heads/main' && github.event_name == 'push'
+ id: generate-code-coverage
+ uses: actions-rs/cargo@v1.0.1
+ with:
+ command: xtask
+ args: coverage
+
+ # Upload the coverage report to codecov
+ - name: Upload coverage report to codecov
+ # Only run this job on the main branch when a commit is pushed.
+ if: github.ref == 'refs/heads/main' && github.event_name == 'push'
+ id: upload-report-codecov
+ uses: codecov/codecov-action@v3
+ with:
+ files: coverage/*.lcov
diff --git a/.gitignore b/.gitignore
index ce3826f..7b5a0e0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,10 @@
*.DS_Store
*.profraw
/.vscode/
+/output/
+/public/
/target/
build
-Cargo.lock
Icon?
src/.DS_Store
+tarpaulin-report.html
diff --git a/AUTHORS.md b/AUTHORS.md
new file mode 100644
index 0000000..9de13ce
--- /dev/null
+++ b/AUTHORS.md
@@ -0,0 +1 @@
+Sebastien Rousseau (Original Contributor)
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..d3245b7
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,1178 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "anes"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
+
+[[package]]
+name = "anstyle"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d"
+
+[[package]]
+name = "anyhow"
+version = "1.0.71"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
+
+[[package]]
+name = "assert_cmd"
+version = "2.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86d6b683edf8d1119fe420a94f8a7e389239666aa72e65495d91c00462510151"
+dependencies = [
+ "anstyle",
+ "bstr",
+ "doc-comment",
+ "predicates",
+ "predicates-core",
+ "predicates-tree",
+ "wait-timeout",
+]
+
+[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi 0.1.19",
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bstr"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3d4260bcc2e8fc9df1eac4919a720effeb63a3f0952f5bf4944adfa18897f09"
+dependencies = [
+ "memchr",
+ "once_cell",
+ "regex-automata",
+ "serde",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
+
+[[package]]
+name = "cast"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
+
+[[package]]
+name = "cc"
+version = "1.0.79"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "ciborium"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0c137568cc60b904a7724001b35ce2630fd00d5d84805fbb608ab89509d788f"
+dependencies = [
+ "ciborium-io",
+ "ciborium-ll",
+ "serde",
+]
+
+[[package]]
+name = "ciborium-io"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "346de753af073cc87b52b2083a506b38ac176a44cfb05497b622e27be899b369"
+
+[[package]]
+name = "ciborium-ll"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "213030a2b5a4e0c0892b6652260cf6ccac84827b83a85a534e178e3906c4cf1b"
+dependencies = [
+ "ciborium-io",
+ "half",
+]
+
+[[package]]
+name = "clap"
+version = "3.2.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5"
+dependencies = [
+ "atty",
+ "bitflags",
+ "clap_lex",
+ "indexmap",
+ "strsim",
+ "termcolor",
+ "textwrap",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
+dependencies = [
+ "os_str_bytes",
+]
+
+[[package]]
+name = "cmn"
+version = "0.0.3"
+dependencies = [
+ "assert_cmd",
+ "criterion",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "console"
+version = "0.15.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60"
+dependencies = [
+ "encode_unicode",
+ "lazy_static",
+ "libc",
+ "unicode-width",
+ "windows-sys 0.42.0",
+]
+
+[[package]]
+name = "criterion"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb"
+dependencies = [
+ "anes",
+ "atty",
+ "cast",
+ "ciborium",
+ "clap",
+ "criterion-plot",
+ "itertools",
+ "lazy_static",
+ "num-traits",
+ "oorandom",
+ "plotters",
+ "rayon",
+ "regex",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "tinytemplate",
+ "walkdir",
+]
+
+[[package]]
+name = "criterion-plot"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
+dependencies = [
+ "cast",
+ "itertools",
+]
+
+[[package]]
+name = "crossbeam-channel"
+version = "0.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
+dependencies = [
+ "cfg-if",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
+dependencies = [
+ "cfg-if",
+ "crossbeam-epoch",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
+dependencies = [
+ "autocfg",
+ "cfg-if",
+ "crossbeam-utils",
+ "memoffset",
+ "scopeguard",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "darling"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850"
+dependencies = [
+ "darling_core",
+ "darling_macro",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim",
+ "syn 1.0.107",
+]
+
+[[package]]
+name = "darling_macro"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e"
+dependencies = [
+ "darling_core",
+ "quote",
+ "syn 1.0.107",
+]
+
+[[package]]
+name = "derive_builder"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8"
+dependencies = [
+ "derive_builder_macro",
+]
+
+[[package]]
+name = "derive_builder_core"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f"
+dependencies = [
+ "darling",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.107",
+]
+
+[[package]]
+name = "derive_builder_macro"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e"
+dependencies = [
+ "derive_builder_core",
+ "syn 1.0.107",
+]
+
+[[package]]
+name = "dialoguer"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59c6f2989294b9a498d3ad5491a79c6deb604617378e1cdc4bfc1c1361fe2f87"
+dependencies = [
+ "console",
+ "shell-words",
+ "tempfile",
+ "zeroize",
+]
+
+[[package]]
+name = "difflib"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
+
+[[package]]
+name = "doc-comment"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
+
+[[package]]
+name = "duct"
+version = "0.13.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37ae3fc31835f74c2a7ceda3aeede378b0ae2e74c8f1c36559fcc9ae2a4e7d3e"
+dependencies = [
+ "libc",
+ "once_cell",
+ "os_pipe",
+ "shared_child",
+]
+
+[[package]]
+name = "either"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
+
+[[package]]
+name = "encode_unicode"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
+
+[[package]]
+name = "errno"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
+dependencies = [
+ "errno-dragonfly",
+ "libc",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "errno-dragonfly"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
+name = "fastrand"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
+dependencies = [
+ "instant",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "fs_extra"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
+
+[[package]]
+name = "glob"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
+
+[[package]]
+name = "half"
+version = "1.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
+
+[[package]]
+name = "ident_case"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+
+[[package]]
+name = "indexmap"
+version = "1.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
+dependencies = [
+ "autocfg",
+ "hashbrown",
+]
+
+[[package]]
+name = "instant"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "io-lifetimes"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220"
+dependencies = [
+ "hermit-abi 0.3.1",
+ "libc",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "itertools"
+version = "0.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
+
+[[package]]
+name = "js-sys"
+version = "0.3.61"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.144"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f"
+
+[[package]]
+name = "log"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "memchr"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+
+[[package]]
+name = "memoffset"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
+dependencies = [
+ "hermit-abi 0.2.6",
+ "libc",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
+
+[[package]]
+name = "oorandom"
+version = "11.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
+
+[[package]]
+name = "os_pipe"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ae859aa07428ca9a929b936690f8b12dc5f11dd8c6992a18ca93919f28bc177"
+dependencies = [
+ "libc",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "os_str_bytes"
+version = "6.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
+
+[[package]]
+name = "plotters"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97"
+dependencies = [
+ "num-traits",
+ "plotters-backend",
+ "plotters-svg",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "plotters-backend"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142"
+
+[[package]]
+name = "plotters-svg"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f"
+dependencies = [
+ "plotters-backend",
+]
+
+[[package]]
+name = "predicates"
+version = "3.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09963355b9f467184c04017ced4a2ba2d75cbcb4e7462690d388233253d4b1a9"
+dependencies = [
+ "anstyle",
+ "difflib",
+ "itertools",
+ "predicates-core",
+]
+
+[[package]]
+name = "predicates-core"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174"
+
+[[package]]
+name = "predicates-tree"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf"
+dependencies = [
+ "predicates-core",
+ "termtree",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.56"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rayon"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7"
+dependencies = [
+ "either",
+ "rayon-core",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b"
+dependencies = [
+ "crossbeam-channel",
+ "crossbeam-deque",
+ "crossbeam-utils",
+ "num_cpus",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "regex"
+version = "1.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733"
+dependencies = [
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
+
+[[package]]
+name = "rustix"
+version = "0.37.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d"
+dependencies = [
+ "bitflags",
+ "errno",
+ "io-lifetimes",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
+
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "scopeguard"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
+[[package]]
+name = "serde"
+version = "1.0.163"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.163"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.15",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.96"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "shared_child"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "shell-words"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
+
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
+[[package]]
+name = "syn"
+version = "1.0.107"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "tempfile"
+version = "3.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "redox_syscall",
+ "rustix",
+ "windows-sys 0.45.0",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "termtree"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76"
+
+[[package]]
+name = "textwrap"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
+
+[[package]]
+name = "tinytemplate"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
+dependencies = [
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
+
+[[package]]
+name = "unicode-width"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
+
+[[package]]
+name = "wait-timeout"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "walkdir"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
+dependencies = [
+ "same-file",
+ "winapi",
+ "winapi-util",
+]
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.84"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.84"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.107",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.84"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.84"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.107",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.84"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
+
+[[package]]
+name = "web-sys"
+version = "0.3.61"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows-sys"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
+dependencies = [
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets 0.42.2",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets 0.48.0",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
+dependencies = [
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
+dependencies = [
+ "windows_aarch64_gnullvm 0.48.0",
+ "windows_aarch64_msvc 0.48.0",
+ "windows_i686_gnu 0.48.0",
+ "windows_i686_msvc 0.48.0",
+ "windows_x86_64_gnu 0.48.0",
+ "windows_x86_64_gnullvm 0.48.0",
+ "windows_x86_64_msvc 0.48.0",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
+
+[[package]]
+name = "xtask"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "xtaskops",
+]
+
+[[package]]
+name = "xtaskops"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "464ca5c2bac1d1fcdbef9da6c09c6a14f2c7ac6c8845f574ab12065a2b72bb8b"
+dependencies = [
+ "anyhow",
+ "clap",
+ "derive_builder",
+ "dialoguer",
+ "duct",
+ "fs_extra",
+ "glob",
+]
+
+[[package]]
+name = "zeroize"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9"
diff --git a/Cargo.toml b/Cargo.toml
index 379a818..5c340b0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,24 +1,34 @@
[package]
-authors = ["Sebastian Rousseau "]
+build = "build.rs"
categories = [
"config",
"cryptography",
- "mathematics",
"data-structures",
"development-tools",
+ "mathematics",
]
description = "A Rust library for accessing a collection of mathematical and cryptographic constants"
+documentation = "https://docs.rs/cmn"
edition = "2021"
+exclude = [
+ "/.git/*",
+ "/.github/*",
+ "/.gitignore",
+ "/.vscode/*"
+ ]
homepage = "https://minifunctions.com/"
keywords = ["cmn", "common", "config", "configurations", "constants"]
license = "MIT OR Apache-2.0"
name = "cmn"
+readme = "README.md"
repository = "https://github.com/sebastienrousseau/cmn/"
-rust-version = "1.67"
-version = "0.0.2"
+rust-version = "1.69.0"
+version = "0.0.3"
include = [
- "../../LICENSE-APACHE",
- "../../LICENSE-MIT",
+ "/CONTRIBUTING.md",
+ "/LICENSE-APACHE",
+ "/LICENSE-MIT",
"/benches/**",
"/build.rs",
"/Cargo.toml",
@@ -26,22 +36,30 @@ include = [
"/README.md",
"/src/**",
"/tests/**",
+ "/xtask/**",
]
+[workspace]
+members = ["xtask"]
+
[[bench]]
-name = "cmn"
+name = "benchmark"
harness = false
-path = "benches/cmn.rs"
+path = "benches/criterion.rs"
+
+[profile.bench]
+debug = true
[[example]]
name = "cmn"
path = "examples/cmn.rs"
[dependencies]
-serde = { version = "1.0.152", features = ["derive"] }
-serde_json = "1.0.92"
+serde = { version = "1.0.163", features = ["derive"] }
+serde_json = "1.0.96"
[dev-dependencies]
+assert_cmd = "2.0.11"
criterion = "0.4.0"
[lib]
diff --git a/README.md b/README.md
index 1d49edc..1d22fe4 100644
--- a/README.md
+++ b/README.md
@@ -1,78 +1,147 @@
-# CMN
+
-A Rust library for accessing a collection of mathematical and cryptographic constants
+
-[![Made With Love][made-with-rust]][6] [![Crates.io][crates-badge]][8] [![Lib.rs][libs-badge]][10] [![Docs.rs][docs-badge]][9] [![License][license-badge]][2] [![Codecov][codecov-badge]][11]
+
-![divider][divider]
+# Common (CMN)
-## Welcome to CMN ๐
+A Rust library for accessing a collection of mathematical and cryptographic constants
-![CMN Banner][banner]
+*Part of the [Mini Functions][0] family of libraries.*
-
+
+
-**[Website][0]
-โข [Documentation][9]
-โข [Report Bug][3]
-โข [Request Feature][3]
-โข [Contributing Guidelines][4]**
+![Common (CMN) Banner][banner]
+[![Made With Rust][made-with-rust-badge]][14] [![Crates.io][crates-badge]][8] [![Lib.rs][libs-badge]][10] [![Docs.rs][docs-badge]][9] [![License][license-badge]][2] [![Codecov][codecov-badge]][15]
+
+โข [Website][1] โข [Documentation][9] โข [Report Bug][4] โข [Request Feature][4] โข [Contributing Guidelines][5]
+
+
+
-
+![divider][divider]
## Overview ๐
-Common (CMN), a Rust library designed for developers who are looking for
-a comprehensive collection of mathematical and cryptographic constants.
-
-`CMN` is a modern, fast, and user-friendly library that makes it easy to
-access a wide range of mathematical and cryptographic constants,
-including the mathematical constant `Euler`, the `hash` algorithm used,
-the `cost` of the hash algorithm, the `length` of the hash, the
-mathematical constant `Phi`, the mathematical constant `Pi`, the
-`Planck` constant, a set of `special` characters, and much more.
+`Common (CMN)` is a modern, fast, and user-friendly library that makes it easy to access a wide range of mathematical and cryptographic constants.
## Features โจ
-The library includes two main structures: `Constant` and `Constants`.
+The `Common (CMN)` uses the `serde` crate to serialize and deserialize the data.
+
+The library has three modules:
+
+- **Macros**: This module contains functions for generating macros that can be used to access the constants.
+- **Constants**: This module contains the Constants structure, which provides a collection of constant values that are used throughout the library.
+- **Words**: This module contains the Words structure, which provides a collection of words that are used throughout the library.
+
+### Mathematical and Cryptographic Constants
+
+The following table lists the most important mathematical and cryptographic constants available in the `Common (CMN)` library:
+
+| Constants | Description | Example |
+| --- | --- | --- |
+| AVOGADRO | Avogadro's constant is the number of atoms or molecules in one mole of a substance. | The number of atoms in 12 grams of carbon-12 is 6.02214076 ร 10^23. This can be used to calculate the number of atoms or molecules in a given sample. |
+| BOLTZMANN | Boltzmann's constant is the physical constant relating the temperature of a system to the average kinetic energy of its constituent particles. | The kinetic energy of an atom at room temperature is about 2.0 ร 10^-21 joules. This can be used to calculate the temperature of a system, or to calculate the average kinetic energy of its particles. |
+| EULER | Euler's constant is a mathematical constant approximately equal to 2.71828. | The sum of the infinite series 1 + 1/2 + 1/3 + ... is equal to Euler's constant, e. This can be used to calculate the sum of an infinite series, or to calculate the logarithm of a number. |
+| GAMMA | The gamma constant is a mathematical constant approximately equal to 0.57721. | The gamma function of 2 is equal to 1. This can be used to calculate the gamma function of a number, or to calculate the factorial of a number. |
+| HASH_ALGORITHM | The hash algorithm used to generate the hash. The default is Blake3. | The hash of the string "Hello, world!" is 5eb63bbbe01eeed093cb22bb8f5acdc32790160b123138d53f2173b8d3dc3eee. This can be used to verify the integrity of data, or to create a unique identifier for a file. |
+| HASH_COST | The cost of the hash. | The hash cost of Blake3 is 2^128. This can be used to determine how secure a hash algorithm is. |
+| HASH_LENGTH | The length of the hash. | The hash length of Blake3 is 32 bytes. This can be used to determine how much space is required to store the hash output. |
+| PHI | The golden ratio is a number approximately equal to 1.618033988749895. | The golden ratio can be used to create a symmetrical design, or a design that is pleasing to the eye. |
+| Pi (ฯ) | Pi is the ratio of a circle's circumference to its diameter. | The circumference of a circle with a radius of 1 is equal to pi. This can be used to calculate the circumference, area, and volume of circles, spheres, and other geometric shapes. |
+| PLANCK | Planck's constant is a physical constant that is approximately equal to 6.62607015 ร 10^โ34 joule seconds. | The energy of a photon of light with a wavelength of 500 nanometers is equal to Planck's constant multiplied by the frequency of the light. This can be used to calculate the energy of photons and other elementary particles. |
+| SILVER_RATIO | The silver ratio is a number approximately equal to 1.414213562373095. | The silver ratio can be used to create a symmetrical design, or a design that is pleasing to the eye. |
+| SPECIAL_CHARS | A list of special characters. | The special characters are: !@#$%^&*()_+-={}[]|\:;"'<>,.? |
+| SQRT2 | The square root of 2 is a number approximately equal to 1.414213562373095. | The area of a circle with a radius of 1 is equal to the square root of 2. This can be used to calculate the area and volume of circles, spheres, and other geometric shapes. |
+| SQRT3 | The square root of 3 is a number approximately equal to 1.732050807568877. | The area of a circle with a radius of 1 is equal to the square root of 3. This can be used to calculate the area and volume of circles
+| SQRT5 | The square root of 5 is a number approximately equal to 2.23606797749979. | The area of a circle with a radius of 1 is equal to the square root of 5. |
+| TAU | Tau is a number approximately equal to 6.283185307179586. | The circumference of a circle with a radius of 1 is equal to tau. |
-- The `Constant` structure holds the name and value of each constant as
-a `&'static str` and a `String`, respectively.
-- The Constants structure implements a method constants that returns a
-`Vec` containing all the available constants.
-- The available constants include the mathematical constants `EULER`,
-`PHI`, `PI`, `PLANCK`, and `SQRT5`, and the cryptographic constants
-`HASH_ALGORITHM`, `HASH_COST`, `HASH_LENGTH`, and `SPECIAL_CHARS`.
-- The library also includes an enumeration `ConstantValue` that
-represents the different constant values. The values can be an
-`f64 float`, a `String`, a `u32`, a `usize`, or a `&'static [char]`
-array of characters.
+## Getting Started ๐
-## Installation ๐ฆ
+It takes just a few minutes to get up and running with `Common (CMN)`.
-It takes just a few minutes to get up and running with `cmn`.
+### Installation
+
+To install `Common (CMN)`, you need to have the Rust toolchain installed on your machine. You can install the Rust toolchain by following the instructions on the [Rust website][14].
+
+Once you have the Rust toolchain installed, you can install `Common (CMN)` using the following command:
+
+```shell
+cargo install cmn
+```
+
+You can then run the help command to see the available options:
+
+```shell
+cmn --help
+```
### Requirements
-`cmn` requires Rust **1.67.0** or later.
+The minimum supported Rust toolchain version is currently Rust **1.69.0** or later (stable). It is recommended that you install the latest stable version of Rust.
+
+### Platform support
+
+`Common (CMN)` is supported and tested on the following platforms:
+
+#### Tier 1 platforms ๐
+
+| Operating System | Target | Description |
+| --- | --- | --- |
+| Linux | aarch64-unknown-linux-gnu | 64-bit Linux systems on ARM architecture |
+| Linux | i686-unknown-linux-gnu | 32-bit Linux (kernel 3.2+, glibc 2.17+) |
+| Linux | x86_64-unknown-linux-gnu | 64-bit Linux (kernel 2.6.32+, glibc 2.11+) |
+| macOS | x86_64-apple-darwin | 64-bit macOS (10.7 Lion or later) |
+| Windows | i686-pc-windows-gnu | 32-bit Windows (7 or later) |
+| Windows | i686-pc-windows-msvc | 32-bit Windows (7 or later) |
+| Windows | x86_64-pc-windows-gnu | 64-bit Windows (7 or later) |
+| Windows | x86_64-pc-windows-msvc | 64-bit Windows (7 or later) |
+
+#### Tier 2 platforms ๐ฅ
+
+| Operating System | Target | Description |
+| --- | --- | --- |
+| 64-bit Linux | x86_64-unknown-linux-musl | 64-bit Linux (kernel 2.6.32+, musl libc) |
+| ARM64 Linux | aarch64-unknown-linux-musl | 64-bit Linux systems on ARM architecture |
+| ARM64 macOS | aarch64-apple-darwin | 64-bit macOS on Apple Silicon |
+| ARM64 Windows | aarch64-pc-windows-msvc | 64-bit Windows (aarch64-pc-windows-msvc) |
+| ARMv6 Linux | arm-unknown-linux-gnueabi | ARMv6 Linux (kernel 3.2, glibc 2.17) |
+| ARMv6 Linux, hardfloat | arm-unknown-linux-gnueabihf | ARMv7 Linux, hardfloat (kernel 3.2, glibc 2.17) |
+| ARMv7 Linux, hardfloat | armv7-unknown-linux-gnueabihf | ARMv7 Linux, hardfloat (kernel 3.2, glibc 2.17) |
+| FreeBSD | x86_64-unknown-freebsd | 64-bit FreeBSD on x86-64 |
+| MIPS (LE) Linux | mipsel-unknown-linux-gnu | MIPSel Linux (kernel 2.6.32+, glibc 2.11+) |
+| MIPS Linux | mips-unknown-linux-gnu | MIPS Linux (kernel 2.6.32+, glibc 2.11+) |
+| MIPS64 (LE) Linux | mips64el-unknown-linux-gnuabi64 | MIPS64el Linux (kernel 2.6.32+, glibc 2.11+) |
+| MIPS64 Linux | mips64-unknown-linux-gnuabi64 | MIPS64 Linux (kernel 2.6.32+, glibc 2.11+) |
+| NetBSD | x86_64-unknown-netbsd | 64-bit NetBSD on x86-64 |
+| PowerPC Linux | powerpc-unknown-linux-gnu | PowerPC Linux (kernel 3.2, glibc 2.17) |
+| PPC64 Linux | powerpc64-unknown-linux-gnu | PowerPC64 Linux (kernel 3.2, glibc 2.17) |
+| PPC64LE Linux | powerpc64le-unknown-linux-gnu | PowerPC64le Linux (kernel 3.2, glibc 2.17) |
+| RISC-V Linux | riscv64gc-unknown-linux-gnu | RISC-V Linux (kernel 3.2, glibc 2.17) |
+| S390x Linux | s390x-unknown-linux-gnu | s390x Linux (kernel 3.2, glibc 2.17) |
+
+The [GitHub Actions][11] shows the platforms in which the `Common (CMN)` library tests are run.
### Documentation
-> โน๏ธ **Info:** Please check out our [website][0] for more information
-and find our documentation on [docs.rs][9], [lib.rs][10] and
-[crates.io][8].
+> โน๏ธ **Info:** Please check out our [website][1] for more information.
+You can find our documentation on [docs.rs][9], [lib.rs][10] and [crates.io][8].
## Usage ๐
-To use `cmn` in your project, add the following to your
-`Cargo.toml` file:
+To use the `Common (CMN)` library in your project, add the following to your `Cargo.toml` file:
```toml
[dependencies]
-cmn = "0.0.2"
+cmn = "0.0.3"
```
Add the following to your `main.rs` file:
@@ -86,10 +155,7 @@ then you can use the functions in your application code.
### Examples
-`CMN` comes with a set of examples that you can use to get started. The
-examples are located in the `examples` directory of the project. To run
-the examples, clone the repository and run the following command in your
-terminal from the project root directory.
+`Common (CMN)` comes with a set of examples that you can use to get started. The examples are located in the `examples` directory of the project. To run the examples, clone the repository and run the following command in your terminal from the project root directory.
```shell
cargo run --example cmn
@@ -97,50 +163,51 @@ cargo run --example cmn
## Semantic Versioning Policy ๐ฅ
-For transparency into our release cycle and in striving to maintain
-backward compatibility, `CMN` follows [semantic versioning][7].
+For transparency into our release cycle and in striving to maintain backward compatibility, `Common (CMN)` follows [semantic versioning][7].
## License ๐
-The project is licensed under the terms of both the MIT license and the
-Apache License (Version 2.0).
+The project is licensed under the terms of both the MIT license and the Apache License (Version 2.0).
-- [Apache License, Version 2.0][1]
-- [MIT license][2]
+- [Apache License, Version 2.0][2]
+- [MIT license][3]
## Contribution ๐ค
-Unless you explicitly state otherwise, any contribution intentionally
-submitted for inclusion in the work by you, as defined in the Apache-2.0
-license, shall be dual licensed as above, without any additional terms
-or conditions.
+We welcome all people who want to contribute. Please see the [contributing instructions][5] for more information.
-![divider][divider]
+Contributions in any form (issues, pull requests, etc.) to this project must adhere to the [Rust's Code of Conduct][12].
+
+Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
## Acknowledgements ๐
-A big thank you to all the awesome contributors of [Mini Functions][6]
-for their help and support. A special thank you goes to the
-[Rust Reddit](https://www.reddit.com/r/rust/) community for providing a
-lot of useful suggestions on how to improve this project.
-
-[0]: https://minifunctions.com/cmn/
-[1]: https://opensource.org/licenses/Apache-2.0
-[2]: http://opensource.org/licenses/MIT
-[3]: https://github.com/sebastienrousseau/cmn/issues
-[4]: https://raw.githubusercontent.com/sebastienrousseau/cmn/main/.github/CONTRIBUTING.md
-[6]: https://github.com/sebastienrousseau/cmn/graphs/contributors
-[7]: http://semver.org/
-[8]: https://crates.io/crates/cmn
-[9]: https://docs.rs/cmn
-[10]: https://lib.rs/crates/cmn
-[11]: https://codecov.io/github/sebastienrousseau/cmn
-
-[banner]: https://raw.githubusercontent.com/sebastienrousseau/vault/main/assets/cmn/banners/banner-cmn-1597x377.svg "CMN Banner"
+A big thank you to all the awesome contributors of the [Common (CMN) Library][6] for their help and support.
+
+A special thank you goes to the [Rust Reddit][13] community for providing a lot of useful suggestions on how to improve this project.
+
+[0]: https://minifunctions.com/ "MiniFunctions"
+[1]: https://cmnlib.one "Common (CMN) Library Website"
+[2]: https://opensource.org/license/apache-2-0/ "Apache License, Version 2.0"
+[3]: https://opensource.org/licenses/MIT "MIT license"
+[4]: https://github.com/sebastienrousseau/cmn/issues "Issues"
+[5]: https://github.com/sebastienrousseau/cmn/blob/main/CONTRIBUTING.md "Contributing Instructions"
+[6]: https://github.com/sebastienrousseau/cmn/graphs/contributors "Contributors"
+[7]: http://semver.org/ "Semantic Versioning"
+[8]: https://crates.io/crates/cmn "Crates.io"
+[9]: https://docs.rs/cmn "Docs.rs"
+[10]: https://lib.rs/crates/cmn "Lib.rs"
+[11]: https://github.com/sebastienrousseau/cmn/actions "GitHub Actions"
+[12]: https://www.rust-lang.org/policies/code-of-conduct "Rust's Code of Conduct"
+[13]: https://reddit.com/r/rust "Rust Reddit"
+[14]: https://www.rust-lang.org "The Rust Programming Language"
+[15]: https://codecov.io/gh/sebastienrousseau/cmn "Codecov"
+
+[banner]: https://kura.pro/cmn/images/titles/title-cmn.svg 'Common (CMN) banner'
[codecov-badge]: https://img.shields.io/codecov/c/github/sebastienrousseau/cmn?style=for-the-badge&token=0FZQGHLMOP 'Codecov'
-[crates-badge]: https://img.shields.io/crates/v/cmn.svg?style=for-the-badge 'Crates.io'
-[divider]: https://raw.githubusercontent.com/sebastienrousseau/vault/main/assets/elements/divider.svg "divider"
-[docs-badge]: https://img.shields.io/docsrs/cmn.svg?style=for-the-badge 'Docs.rs'
-[libs-badge]: https://img.shields.io/badge/lib.rs-v0.0.2-orange.svg?style=for-the-badge 'Lib.rs'
-[license-badge]: https://img.shields.io/crates/l/cmn.svg?style=for-the-badge 'License'
-[made-with-rust]: https://img.shields.io/badge/rust-f04041?style=for-the-badge&labelColor=c0282d&logo=rust 'Made With Rust'
+[crates-badge]: https://img.shields.io/crates/v/cmn.svg?style=for-the-badge 'Crates.io badge'
+[divider]: https://kura.pro/common/images/elements/divider.svg "divider"
+[docs-badge]: https://img.shields.io/docsrs/cmn.svg?style=for-the-badge 'Docs.rs badge'
+[libs-badge]: https://img.shields.io/badge/lib.rs-v0.0.3-orange.svg?style=for-the-badge 'Lib.rs badge'
+[license-badge]: https://img.shields.io/crates/l/cmn.svg?style=for-the-badge 'License badge'
+[made-with-rust-badge]: https://img.shields.io/badge/rust-f04041?style=for-the-badge&labelColor=c0282d&logo=rust 'Made With Rust badge'
diff --git a/TEMPLATE.md b/TEMPLATE.md
new file mode 100644
index 0000000..2d690a2
--- /dev/null
+++ b/TEMPLATE.md
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+# Common (CMN)
+
+A Rust library for accessing a collection of mathematical and cryptographic constants
+
+*Part of the [Mini Functions][0] family of libraries.*
+
+
+
+
+
+![Common (CMN) Banner][banner]
+
+[![Made With Rust][made-with-rust-badge]][14] [![Crates.io][crates-badge]][8] [![Lib.rs][libs-badge]][10] [![Docs.rs][docs-badge]][9] [![License][license-badge]][2] [![Codecov][codecov-badge]][15]
+
+โข [Website][1] โข [Documentation][9] โข [Report Bug][4] โข [Request Feature][4] โข [Contributing Guidelines][5]
+
+
+
+
+
+![divider][divider]
+
+## Overview ๐
+
+`Common (CMN)`, a Rust library designed for developers who are looking for a comprehensive collection of mathematical and cryptographic constants.
+
+`Common (CMN)` is a modern, fast, and user-friendly library that makes it easy to access a wide range of mathematical and cryptographic constants, including the mathematical constant `Euler`, the `hash` algorithm used, the `cost` of the hash algorithm, the `length` of the hash, the mathematical constant `Phi`, the mathematical constant `Pi`, the `Planck` constant, a set of `special` characters, and much more.
+
+## Features โจ
+
+The library includes two main structures: `Constant` and `Constants`.
+
+- The `Constant` structure holds the name and value of each constant as
+a `&'static str` and a `String`, respectively.
+- The Constants structure implements a method constants that returns a
+`Vec` containing all the available constants.
+- The available constants include the mathematical constants `EULER`,
+`PHI`, `PI`, `PLANCK`, and `SQRT5`, and the cryptographic constants
+`HASH_ALGORITHM`, `HASH_COST`, `HASH_LENGTH`, and `SPECIAL_CHARS`.
+- The library also includes an enumeration `ConstantValue` that
+represents the different constant values. The values can be an
+`f64 float`, a `String`, a `u32`, a `usize`, or a `&'static [char]`
+array of characters.
+
+[0]: https://minifunctions.com/ "MiniFunctions"
+[1]: https://cmnlib.one "Common (CMN) Library Website"
+[2]: https://opensource.org/license/apache-2-0/ "Apache License, Version 2.0"
+[4]: https://github.com/sebastienrousseau/cmn/issues "Issues"
+[5]: https://github.com/sebastienrousseau/cmn/blob/main/CONTRIBUTING.md "Contributing Instructions"
+[8]: https://crates.io/crates/cmn "Crates.io"
+[9]: https://docs.rs/cmn "Docs.rs"
+[10]: https://lib.rs/crates/cmn "Lib.rs"
+[14]: https://www.rust-lang.org "The Rust Programming Language"
+[15]: https://codecov.io/gh/sebastienrousseau/cmn "Codecov"
+
+[banner]: https://kura.pro/cmn/images/titles/title-cmn.svg 'Common (CMN) banner'
+[codecov-badge]: https://img.shields.io/codecov/c/github/sebastienrousseau/cmn?style=for-the-badge&token=0FZQGHLMOP 'Codecov'
+[crates-badge]: https://img.shields.io/crates/v/cmn.svg?style=for-the-badge 'Crates.io badge'
+[divider]: https://kura.pro/common/images/elements/divider.svg "divider"
+[docs-badge]: https://img.shields.io/docsrs/cmn.svg?style=for-the-badge 'Docs.rs badge'
+[libs-badge]: https://img.shields.io/badge/lib.rs-v0.0.3-orange.svg?style=for-the-badge 'Lib.rs badge'
+[license-badge]: https://img.shields.io/crates/l/cmn.svg?style=for-the-badge 'License badge'
+[made-with-rust-badge]: https://img.shields.io/badge/rust-f04041?style=for-the-badge&labelColor=c0282d&logo=rust 'Made With Rust badge'
+
+## Changelog ๐
diff --git a/benches/cmn.rs b/benches/criterion.rs
similarity index 77%
rename from benches/cmn.rs
rename to benches/criterion.rs
index a889a44..52eac87 100644
--- a/benches/cmn.rs
+++ b/benches/criterion.rs
@@ -1,4 +1,10 @@
-use criterion::{black_box, criterion_group, criterion_main, Criterion};
+// Copyright ยฉ 2023 Common (CMN) library. All rights reserved.
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
+//! Benchmarks for the Common (CMN) library.
+use criterion::{
+ black_box, criterion_group, criterion_main, Criterion,
+};
pub use cmn::Common;
pub use cmn::Constants;
diff --git a/build.rs b/build.rs
index 7883592..77de8d3 100644
--- a/build.rs
+++ b/build.rs
@@ -1,4 +1,14 @@
+// Copyright ยฉ 2023 Common (CMN) library. All rights reserved.
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
+//! The main function of the build script.
+//!
+//! This function is executed when building the crate and performs certain tasks
+//! necessary for the build process.
+//!
+//! It prints a "cargo:rerun-if-changed" directive to indicate that the build
+//! should be re-run if the "build.rs" file is changed.
fn main() {
// println!("cargo:rerun-if-changed=src/lib.rs");
- // println!("cargo:rerun-if-changed=build.rs");
+ println!("cargo:rerun-if-changed=build.rs");
}
diff --git a/deny.toml b/deny.toml
index 403a345..2670118 100644
--- a/deny.toml
+++ b/deny.toml
@@ -5,12 +5,22 @@ unlicensed = "deny"
# List of explicitly allowed licenses
# See https://spdx.org/licenses/ for list of possible licenses
# [possible values: any SPDX 3.7 short identifier (+ optional exception)].
-allow = ["MPL-2.0"]
+allow = [
+ "Apache-2.0",
+ "MIT",
+ "CC0-1.0",
+ "ISC",
+ "0BSD",
+ "BSD-2-Clause",
+ "BSD-3-Clause",
+ "Unlicense",
+ "Unicode-DFS-2016",
+]
+
+# List of banned licenses
+[bans]
+multiple-versions = "deny"
-# List of explicitly disallowed licenses
-# See https://spdx.org/licenses/ for list of possible licenses
-# [possible values: any SPDX 3.7 short identifier (+ optional exception)].
-deny = []
# The lint level for licenses considered copyleft
copyleft = "deny"
@@ -29,10 +39,6 @@ allow-osi-fsf-free = "either"
# [possible values: any between 0.0 and 1.0].
confidence-threshold = 0.8
-[bans]
-# Lint level for when multiple versions of the same crate are detected
-multiple-versions = "warn"
-
# The graph highlighting used when creating dotgraphs for crates
# with multiple versions
# * lowest-version - The path to the lowest versioned duplicate is highlighted
@@ -41,8 +47,7 @@ multiple-versions = "warn"
highlight = "all"
# List of crates that are allowed. Use with care!
-allow = [
-]
+allow = []
# List of crates to deny
deny = [
@@ -51,16 +56,16 @@ deny = [
]
# Certain crates/versions that will be skipped when doing duplicate detection.
-skip = [
-]
+skip = []
# Similarly to `skip` allows you to skip certain crates during duplicate detection,
# unlike skip, it also includes the entire tree of transitive dependencies starting at
# the specified crate, up to a certain depth, which is by default infinite
-skip-tree = [
-]
+skip-tree = []
[advisories]
-ignore = [
-]
+notice = "deny"
+unmaintained = "deny"
+unsound = "deny"
+vulnerability = "deny"
diff --git a/examples/cmn.rs b/examples/cmn.rs
index dac5f16..a96f16f 100644
--- a/examples/cmn.rs
+++ b/examples/cmn.rs
@@ -1,7 +1,11 @@
-extern crate cmn;
+// Copyright ยฉ 2023 Common (CMN) library. All rights reserved.
+// SPDX-License-Identifier: Apache-2.0 OR MIT
-use cmn::constants::{Constant, ConstantValue, Constants};
-pub use cmn::Words;
+//! Examples of how to use the Common (CMN) library.
+use cmn::{
+ cmn_constants,
+ constants::{Constant, ConstantValue, Constants},
+};
fn main() {
// Create a Constants instance
@@ -20,7 +24,8 @@ fn main() {
static JSON: &str = r#"[{"name":"EULER","value":"2.718281828459045"},{"name":"PI","value":"3.141592653589793"},{"name":"TAU","value":"6.283185307179586"},{"name":"SQRT2","value":"1.4142135623730951"},{"name":"SQRT1_2","value":"0.7071067811865476"},{"name":"LN2","value":"0.6931471805599453"},{"name":"LN10","value":"2.302585092994046"},{"name":"LOG2E","value":"1.4426950408889634"},{"name":"LOG10E","value":"0.4342944819032518"},{"name":"PHI","value":"1.618033988749895"},{"name":"GOLDEN_RATIO","value":"1.618033988749895"},{"name":"INFINITY","value":"Infinity"},{"name":"NEG_INFINITY","value":"-Infinity"},{"name":"NAN","value":"NaN"}]"#;
// Deserialize the constants from the JSON string
- let deserialized: Vec = serde_json::from_str(JSON).unwrap();
+ let deserialized: Vec =
+ serde_json::from_str(JSON).unwrap();
// Print the deserialized constants
println!("๐ฆ Deserialized: โ
{deserialized:?}");
@@ -32,4 +37,33 @@ fn main() {
// Retrieve a constant by name and print it (in this case, EULER)
let euler_constant = c.constant("EULER");
println!("๐ฆ ConstantValue of EULER: โ
{euler_constant:?}");
+
+ // Retrieve a constant by name and print it (in this case, PI)
+ cmn_constants! {
+ AVOGADRO = cmn::constants::AVOGADRO,
+ BOLTZMANN = cmn::constants::BOLTZMANN,
+ EULER = cmn::constants::EULER,
+ GAMMA = cmn::constants::GAMMA,
+ PHI = cmn::constants::PHI,
+ PI = cmn::constants::PI,
+ PLANCK = cmn::constants::PLANCK,
+ SILVER_RATIO = cmn::constants::SILVER_RATIO,
+ SQRT2 = cmn::constants::SQRT2,
+ SQRT3 = cmn::constants::SQRT3,
+ SQRT5 = cmn::constants::SQRT5,
+ TAU = cmn::constants::TAU
+ }
+ println!("๐ฆ Using cmn_constants! macro:");
+ println!("- Avogadro's constant: โ
{}", &AVOGADRO);
+ println!("- Boltzmann's constant: โ
{}", &BOLTZMANN);
+ println!("- Euler's constant: โ
{}", &EULER);
+ println!("- Gamma's constant: โ
{}", &GAMMA);
+ println!("- Phi's constant: โ
{}", &PHI);
+ println!("- Pi's constant: โ
{}", &PI);
+ println!("- Planck's constant: โ
{}", &PLANCK);
+ println!("- Silver ratio's constant: โ
{}", &SILVER_RATIO);
+ println!("- Sqrt2's constant: โ
{}", &SQRT2);
+ println!("- Sqrt3's constant: โ
{}", &SQRT3);
+ println!("- Sqrt5's constant: โ
{}", &SQRT5);
+ println!("- Tau's constant: โ
{}", &TAU);
}
diff --git a/rustfmt.toml b/rustfmt.toml
index 19c3710..0e0d4c4 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -1 +1,4 @@
-# default
\ No newline at end of file
+edition = "2021"
+max_width = 72
+tab_spaces = 4
+use_field_init_shorthand = true
\ No newline at end of file
diff --git a/src/constants.rs b/src/constants.rs
index ec68a9f..9ff26c3 100644
--- a/src/constants.rs
+++ b/src/constants.rs
@@ -1,11 +1,21 @@
-// Copyright ยฉ 2022-2023 Mini Functions. All rights reserved.
-// SPDX-License-Identifier: Apache-2.0
-// SPDX-License-Identifier: MIT
+// Copyright ยฉ 2023 Common (CMN) library. All rights reserved.
+// SPDX-License-Identifier: Apache-2.0 OR MIT
use serde::{Deserialize, Serialize};
/// Contains several commonly used mathematical and cryptographic constants.
-#[derive(Clone, Serialize, Deserialize, Debug, Default, PartialEq)]
+#[non_exhaustive]
+#[derive(
+ Clone,
+ Debug,
+ Eq,
+ Hash,
+ Ord,
+ PartialEq,
+ PartialOrd,
+ Serialize,
+ Deserialize,
+)]
pub struct Constant {
/// The name of the constant.
pub name: &'static str,
@@ -72,12 +82,20 @@ impl Constants {
/// use cmn::constants::Constants;
///
/// let constants = Constants::new();
- /// assert_eq!(constants.constants().len(), 13);
+ /// assert_eq!(constants.constants().len(), 16);
///
/// ```
///
pub fn new() -> Self {
let constants = vec![
+ Constant {
+ name: "AVOGADRO",
+ value: AVOGADRO.to_string(),
+ },
+ Constant {
+ name: "BOLTZMANN",
+ value: BOLTZMANN.to_string(),
+ },
Constant {
name: "EULER",
value: EULER.to_string(),
@@ -130,6 +148,10 @@ impl Constants {
name: "SQRT5",
value: SQRT5.to_string(),
},
+ Constant {
+ name: "TAU",
+ value: TAU.to_string(),
+ },
];
Self { constants }
@@ -138,9 +160,9 @@ impl Constants {
/// Returns `true` if the `Constants` structure is valid.
/// Otherwise, returns `false`.
pub fn is_valid(&self) -> bool {
- self.constants()
- .iter()
- .all(|constant| !constant.name.is_empty() && !constant.value.is_empty())
+ self.constants().iter().all(|constant| {
+ !constant.name.is_empty() && !constant.value.is_empty()
+ })
}
}
@@ -166,18 +188,22 @@ pub enum ConstantValue {
CharArray(&'static [char]),
}
-/// The mathematical Euler number (e), Napier's constant, the base of
-/// the natural logarithm.
-/// e^{\ln x}=x
-/// - `ln` being the natural logarithm
-/// - `e` being the natural exponent
-/// - `x` being the real number
+/// Avogadro's constant
+/// Approximately 6.02214076 x 10^23
+pub const AVOGADRO: f64 = 602214076000000000000000.0;
+
+/// Boltzmann's constant
+/// Approximately 1.380648 x 10^-23
+pub const BOLTZMANN: f64 = 1.380648e-23;
+
+/// The base of the natural logarithm, Euler's number (e).
+/// e โ 2.7182818284590452353602874713527
pub const EULER: f64 = std::f64::consts::E;
/// The mathematical constant `ฮณ` or the EulerโMascheroni constant. It
/// is the limit of the difference between the harmonic series and the
/// natural logarithm of the natural numbers.
-pub const GAMMA: f64 = 0.577_215_664_901_532_9_f64;
+pub const GAMMA: f64 = 0.5772156649015329;
/// The hash algorithm used. The default is Blake3.
pub const HASH_ALGORITHM: &str = "Blake3";
@@ -201,7 +227,7 @@ pub const PHI: f64 = (1.0 + SQRT5) / 2.0;
pub const PI: f64 = std::f64::consts::PI;
/// The Planck constant, `h`.
-pub const PLANCK: f64 = 6.626_070_15e-34_f64;
+pub const PLANCK: f64 = 6.62607015e-34;
/// The mathematical constant `ฮดs' or the silver ratio (or silver mean).
/// ฮดs = 1+โ2. One of the silver means (n+sqrt(n2+1))/2 for n>0.
@@ -209,8 +235,9 @@ pub const SILVER_RATIO: f64 = 1.0 + SQRT2;
/// A set of special characters.
pub const SPECIAL_CHARS: &[char] = &[
- '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '=', '[', ']', '{', '}', '|', ';',
- ':', '"', '<', '>', ',', '.', '?', '/', '~', '`',
+ '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '=',
+ '[', ']', '{', '}', '|', ';', ':', '"', '<', '>', ',', '.', '?',
+ '/', '~', '`',
];
/// The mathematical constant `โ2` or the Pythagora's constant or the
@@ -223,10 +250,14 @@ pub const SQRT2: f64 = std::f64::consts::SQRT_2;
/// It is the length of the side of an equilateral triangle with unit
/// side length.
/// 3 = 1 + โ3
-pub const SQRT3: f64 = 1.732_050_807_568_877_2_f64;
+pub const SQRT3: f64 = 1.732_050_807_568_877_2;
/// The mathematical constant `โ5` or the principal square root of 5.
/// It is the length of the diagonal of a regular pentagon with unit
/// side length.
/// 5 = 2 + 2โ5
-pub const SQRT5: f64 = 2.236_067_977_499_79_f64;
+pub const SQRT5: f64 = 2.236_067_977_499_79;
+
+/// The mathematical constant `ฯ` or the ratio of a circle's
+/// circumference to its radius.
+pub const TAU: f64 = std::f64::consts::TAU;
diff --git a/src/lib.rs b/src/lib.rs
index 56f471e..9438603 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,54 +1,60 @@
-// Copyright ยฉ 2022-2023 Mini Functions. All rights reserved.
-// SPDX-License-Identifier: Apache-2.0
-// SPDX-License-Identifier: MIT
+// Copyright ยฉ 2023 Common (CMN) library. All rights reserved.
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
//!
//! A Rust library for accessing a collection of mathematical and
//! cryptographic constants
//!
-//! [![Rust](https://raw.githubusercontent.com/sebastienrousseau/vault/main/assets/cmn/logo/logo-cmn.svg)](https://minifunctions.com/cmn)
+//! *Part of the [Mini Functions][0] family of libraries.*
+//!
+//! [![Common (CMN)](https://kura.pro/cmn/images/titles/title-cmn.svg)](https://minifunctions.com/cmn)
//!
//!
//!
-//! [![Rust](https://img.shields.io/badge/rust-f04041?style=for-the-badge&labelColor=c0282d&logo=rust)](https://www.rust-lang.org)
//! [![Crates.io](https://img.shields.io/crates/v/cmn.svg?style=for-the-badge&color=success&labelColor=27A006)](https://crates.io/crates/cmn)
-//! [![Lib.rs](https://img.shields.io/badge/lib.rs-v0.0.2-success.svg?style=for-the-badge&color=8A48FF&labelColor=6F36E4)](https://lib.rs/crates/cmn)
//! [![GitHub](https://img.shields.io/badge/github-555555?style=for-the-badge&labelColor=000000&logo=github)](https://github.com/sebastienrousseau/cmn)
+//! [![Lib.rs](https://img.shields.io/badge/lib.rs-v0.0.3-success.svg?style=for-the-badge&color=8A48FF&labelColor=6F36E4)](https://lib.rs/crates/cmn)
//! [![License](https://img.shields.io/crates/l/cmn.svg?style=for-the-badge&color=007EC6&labelColor=03589B)](http://opensource.org/licenses/MIT)
+//! [![Rust](https://img.shields.io/badge/rust-f04041?style=for-the-badge&labelColor=c0282d&logo=rust)](https://www.rust-lang.org)
//!
//!
//!
-//! ## Overview
+//! ## Overview ๐
//!
-//! Common (CMN), a Rust library designed for developers who are looking
-//! for a comprehensive collection of mathematical and cryptographic
-//! constants.
+//! `Common (CMN)` is a modern, fast, and user-friendly library that makes it easy to access a wide range of mathematical and cryptographic constants.
//!
-//!`CMN` is a modern, fast, and user-friendly library that makes it easy
-//! to access a wide range of mathematical and cryptographic constants,
-//! including the mathematical constant "Euler", the hash algorithm
-//! used, the cost of the hash algorithm, the length of the hash, the
-//! mathematical constant "Phi", the mathematical constant "Pi", the
-//! Planck constant, a set of special characters, and much more.
+//! ## Features โจ
//!
-//! ## Features
+//! The `Common (CMN)` uses the `serde` crate to serialize and deserialize the data.
//!
-//! The following table lists the Constants available in the Common
-//! library.
+//! The library has three modules:
//!
-//!| Constants | Description |
-//!| --- | --- |
-//!| `EULER` | Euler's constant is a mathematical constant approximately equal to 2.71828. |
-//!| `GAMMA` | The gamma constant is a mathematical constant approximately equal to 0.57721. |
-//!| `HASH_ALGORITHM` | The hash algorithm used to generate the hash. The default is Blake3. |
-//!| `HASH_COST` | The cost of the hash. |
-//!| `HASH_LENGTH` | The length of the hash. |
-//!| `PHI` | The golden ratio is a number approximately equal to 1.618033988749895. |
-//!| `PI` | Pi is the ratio of a circle's circumference to its diameter. |
-//!| `PLANCK` | Planck's constant is a physical constant that is approximately equal to 6.62607015 ร 10โ34 joule seconds. |
-//!| `SILVER_RATIO` | The silver ratio is a number approximately equal to 1.414213562373095. |
-//!| `SPECIAL_CHARS` | A list of special characters. |
-//!| `SQRT2` | The square root of 2 is a number approximately equal to 1.414213562373095. |
-//!| `SQRT5` | The square root of 5 is a number approximately equal to 2.23606797749979. |
+//! - **Macros**: This module contains functions for generating macros that can be used to access the constants.
+//! - **Constants**: This module contains the Constants structure, which provides a collection of constant values that are used throughout the library.
+//! - **Words**: This module contains the Words structure, which provides a collection of words that are used throughout the library.
+//!
+//! ### Mathematical and Cryptographic Constants
+//!
+//! The following table lists the most important mathematical and cryptographic constants available in the `Common (CMN)` library:
+//!
+//!| Constants | Description | Example |
+//!| --- | --- | --- |
+//!| AVOGADRO | Avogadro's constant is the number of atoms or molecules in one mole of a substance. | The number of atoms in 12 grams of carbon-12 is 6.02214076 ร 10^23. This can be used to calculate the number of atoms or molecules in a given sample. |
+//!| BOLTZMANN | Boltzmann's constant is the physical constant relating the temperature of a system to the average kinetic energy of its constituent particles. | The kinetic energy of an atom at room temperature is about 2.0 ร 10^-21 joules. This can be used to calculate the temperature of a system, or to calculate the average kinetic energy of its particles. |
+//!| EULER | Euler's constant is a mathematical constant approximately equal to 2.71828. | The sum of the infinite series 1 + 1/2 + 1/3 + ... is equal to Euler's constant, e. This can be used to calculate the sum of an infinite series, or to calculate the logarithm of a number. |
+//!| GAMMA | The gamma constant is a mathematical constant approximately equal to 0.57721. | The gamma function of 2 is equal to 1. This can be used to calculate the gamma function of a number, or to calculate the factorial of a number. |
+//!| HASH_ALGORITHM | The hash algorithm used to generate the hash. The default is Blake3. | The hash of the string "Hello, world!" is 5eb63bbbe01eeed093cb22bb8f5acdc32790160b123138d53f2173b8d3dc3eee. This can be used to verify the integrity of data, or to create a unique identifier for a file. |
+//!| HASH_COST | The cost of the hash. | The hash cost of Blake3 is 2^128. This can be used to determine how secure a hash algorithm is. |
+//!| HASH_LENGTH | The length of the hash. | The hash length of Blake3 is 32 bytes. This can be used to determine how much space is required to store the hash output. |
+//!| PHI | The golden ratio is a number approximately equal to 1.618033988749895. | The golden ratio can be used to create a symmetrical design, or a design that is pleasing to the eye. |
+//!| PI | Pi is the ratio of a circle's circumference to its diameter. | The circumference of a circle with a radius of 1 is equal to pi. This can be used to calculate the circumference, area, and volume of circles, spheres, and other geometric shapes. |
+//!| PLANCK | Planck's constant is a physical constant that is approximately equal to 6.62607015 ร 10^โ34 joule seconds. | The energy of a photon of light with a wavelength of 500 nanometers is equal to Planck's constant multiplied by the frequency of the light. This can be used to calculate the energy of photons and other elementary particles. |
+//!| SILVER_RATIO | The silver ratio is a number approximately equal to 1.414213562373095. | The silver ratio can be used to create a symmetrical design, or a design that is pleasing to the eye. |
+//!| SPECIAL_CHARS | A list of special characters. | The special characters are: !@#$%^&*()_+-={}[]|\:;"'<>,.? |
+//!| SQRT2 | The square root of 2 is a number approximately equal to 1.414213562373095. | The area of a circle with a radius of 1 is equal to the square root of 2. This can be used to calculate the area and volume of circles, spheres, and other geometric shapes. |
+//!| SQRT3 | The square root of 3 is a number approximately equal to 1.732050807568877. | The area of a circle with a radius of 1 is equal to the square root of 3. This can be used to calculate the area and volume of circles
+//!| SQRT5 | The square root of 5 is a number approximately equal to 2.23606797749979. | The area of a circle with a radius of 1 is equal to the square root of 5. |
+//!| TAU | Tau is a number approximately equal to 6.283185307179586. | The circumference of a circle with a radius of 1 is equal to tau. |
//!
//! The following table lists the dictionaries available in the Common
//! library.
@@ -93,11 +99,17 @@
//! defined in the Apache-2.0 license, shall be dual licensed as above,
//! without any additional terms or conditions.
//!
-#![warn(missing_docs)]
+//! [0]: https://minifunctions.com/ "MiniFunctions"
+//!
+#![cfg_attr(feature = "bench", feature(test))]
+#![deny(dead_code)]
+#![deny(missing_debug_implementations)]
+#![deny(missing_docs)]
#![forbid(unsafe_code)]
+#![warn(unreachable_pub)]
#![doc(
- html_logo_url = "https://raw.githubusercontent.com/sebastienrousseau/vault/main/assets/cmn/icons/ico-cmn.svg",
- html_favicon_url = "https://raw.githubusercontent.com/sebastienrousseau/vault/main/assets/cmn/icons/ico-cmn.svg",
+ html_favicon_url = "https://kura.pro/cmn/images/favicon.ico",
+ html_logo_url = "https://kura.pro/cmn/images/logos/cmn.svg",
html_root_url = "https://docs.rs/cmn"
)]
#![crate_name = "cmn"]
@@ -108,6 +120,9 @@
extern crate serde;
use serde::{Deserialize, Serialize};
+/// The `macros` module contains functions for generating macros.
+pub mod macros;
+
/// The `constants` module contains the `Constants` structure, which
/// provides a collection of constant values that are used throughout
/// the library.
@@ -123,6 +138,11 @@ pub use words::Words;
/// that is commonly used throughout the library. The structure
/// implements the `Serialize` and `Deserialize` traits from the `serde`
/// crate to enable serialization and deserialization of the data.
+///
+/// # Fields
+///
+/// * `constants`: A reference to the `Constants` structure.
+/// * `words`: A reference to the `Words` structure.
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct Common;
@@ -141,6 +161,14 @@ impl Common {
pub fn words(&self) -> Words {
Words::new()
}
+ /// Parses a string of JSON data and returns a new instance of the
+ /// `Common` structure.
+ pub fn parse(
+ input: &str,
+ ) -> Result> {
+ let common: Common = serde_json::from_str(input)?;
+ Ok(common)
+ }
}
impl Default for Common {
@@ -150,3 +178,16 @@ impl Default for Common {
Self::new()
}
}
+
+/// This is the main entry point for the `Common (CMN)` library.
+pub fn run() -> Result<(), Box> {
+ if std::env::var("CMN_TEST_MODE").unwrap_or_default() == "1" {
+ return Err("Simulated error".into());
+ }
+ let name = "cmn";
+ println!("Welcome to `{}` ๐!", { name }.to_uppercase());
+ println!(
+ "A Rust library for accessing a collection of mathematical and cryptographic constants."
+ );
+ Ok(())
+}
diff --git a/src/macros.rs b/src/macros.rs
new file mode 100644
index 0000000..ed7ff54
--- /dev/null
+++ b/src/macros.rs
@@ -0,0 +1,186 @@
+// Copyright ยฉ 2023 Common (CMN) library. All rights reserved.
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
+//! Macros for the cmn crate.
+//!
+//! This module bundles all macros used across the cmn crate.
+//! These include macros for validating input, and macros for
+//! generating the Common struct.
+//!
+//! ## Generic macros for the cmn crate.
+//!
+//! This crate provides the following macros:
+//!
+//! | Macro | Description |
+//! |--------|------------|
+//! | `cmn` | The main macro for the cmn crate. It takes any number of arguments and parses them into a Rust value. |
+//! | `cmn_assert` | Checks if the given expression is true. |
+//! | `cmn_contains` | Checks if the given string contains the given substring. |
+//! | `cmn_in_range` | Checks if the given value is in the given range. |
+//! | `cmn_join` | Joins a vector of strings into a single string. |
+//! | `cmn_map` | Creates a new map of the given key-value pairs. |
+//! | `cmn_max` | Returns the maximum of the given values. |
+//! | `cmn_min` | Returns the minimum of the given values. |
+//! | `cmn_parse` | Parses the given input into a Rust value. |
+//! | `cmn_print_vec` | Prints a vector of elements to the console. |
+//! | `cmn_print` | Prints the arguments to the console. |
+//! | `cmn_split` | Splits a string into a vector of words. |
+//! | `cmn_to_num` | Converts the given string to a number. |
+//! | `cmn_vec` | Creates a new vector of the given elements. |
+//!
+
+/// This macro takes any number of arguments and parses them into a
+/// Rust value.
+#[macro_export]
+macro_rules! cmn {
+ ($($tt:tt)*) => {
+ cmn::Common::parse($($tt)*)
+ };
+}
+
+/// This macro asserts that the given condition is true. If the
+/// condition is false, the macro panics with the given message.
+#[macro_export]
+macro_rules! cmn_assert {
+ ($($arg:tt)*) => {
+ if !$($arg)* {
+ panic!("Assertion failed!");
+ }
+ };
+}
+
+/// This macro checks if the given string contains the given substring.
+#[macro_export]
+macro_rules! cmn_contains {
+ ($s:expr, $sub:expr) => {
+ $s.contains($sub)
+ };
+}
+
+/// This macro checks if the given value is within the given range.
+#[macro_export]
+macro_rules! cmn_in_range {
+ ($value:expr, $min:expr, $max:expr) => {
+ if $value >= $min && $value <= $max {
+ true
+ } else {
+ false
+ }
+ };
+}
+
+/// This macro joins the given strings together with the given separator.
+#[macro_export]
+macro_rules! cmn_join {
+ ($($s:expr),*) => {{
+ let mut s = String::new();
+ $(
+ s += &$s;
+ )*
+ s
+ }};
+}
+
+/// This macro finds the maximum value of the given values.
+#[macro_export]
+macro_rules! cmn_max {
+ ($x:expr $(, $y:expr)*) => {{
+ let mut max = $x;
+ $(
+ if max < $y { max = $y; }
+ )*
+ max
+ }};
+}
+
+/// This macro finds the minimum value of the given values.
+#[macro_export]
+macro_rules! cmn_min {
+ ($x:expr $(, $y:expr)*) => {{
+ let mut min = $x;
+ $(
+ if min > $y { min = $y; }
+ )*
+ min
+ }};
+}
+
+/// This macro prints the given arguments to the console.
+#[macro_export]
+macro_rules! cmn_print {
+ ($($arg:tt)*) => {
+ println!("{}", format_args!("{}", $($arg)*));
+ };
+}
+
+/// This macro prints the given vector of values to the console.
+#[macro_export]
+macro_rules! cmn_print_vec {
+ ($($v:expr),*) => {{
+ for v in $($v),* {
+ println!("{}", v);
+ }
+ }};
+}
+
+/// This macro splits the given string into a vector of strings.
+#[macro_export]
+macro_rules! cmn_split {
+ ($s:expr) => {{
+ let mut v = Vec::new();
+ for w in $s.split_whitespace() {
+ v.push(w.to_string());
+ }
+ v
+ }};
+}
+
+/// This macro creates a new vector with the given elements.
+#[macro_export]
+macro_rules! cmn_vec {
+ ($($elem:expr),*) => {{
+ let mut v = Vec::new();
+ $(v.push($elem);)*
+ v
+ }};
+}
+
+/// This macro parses the given input into a Rust value.
+#[macro_export]
+macro_rules! cmn_parse {
+ ($input:expr) => {
+ Common::parse($input)
+ };
+}
+
+/// This macro defines a set of constants with their corresponding
+/// values. The macros can be used to define constants in a concise
+/// and easy-to-read way.
+#[macro_export]
+macro_rules! cmn_constants {
+ ($($name:ident = $value:expr),*) => {
+ $(
+ /// The value of the constant.
+ pub const $name: f64 = $value;
+ )*
+ };
+}
+
+// cmn_constants! {
+// AVOGADRO = super::constants::AVOGADRO,
+// BOLTZMANN = super::constants::BOLTZMANN,
+// EULER = super::constants::EULER,
+// GAMMA = super::constants::GAMMA,
+// HASH_ALGORITHM = super::constants::HASH_ALGORITHM,
+// HASH_COST = super::constants::HASH_COST,
+// HASH_LENGTH = super::constants::HASH_LENGTH,
+// PHI = super::constants::PHI,
+// PI = super::constants::PI,
+// PLANCK = super::constants::PLANCK,
+// SILVER_RATIO = super::constants::SILVER_RATIO,
+// SPECIAL_CHARS = super::constants::SPECIAL_CHARS,
+// SQRT2 = super::constants::SQRT2,
+// SQRT3 = super::constants::SQRT3,
+// SQRT5 = super::constants::SQRT5,
+// TAU = super::constants::TAU
+// }
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..90bbc3f
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,11 @@
+// Copyright ยฉ 2023 Common (CMN) library. All rights reserved.
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
+//! This is the main entry point for the cmn application.
+fn main() {
+ // Call the `run()` function from the `Common (CMN)` module.
+ if let Err(err) = cmn::run() {
+ eprintln!("Error running cmn: {}", err);
+ std::process::exit(1);
+ }
+}
diff --git a/src/words.rs b/src/words.rs
index 4d959b8..ff16157 100644
--- a/src/words.rs
+++ b/src/words.rs
@@ -1,6 +1,5 @@
-// Copyright ยฉ 2022-2023 Mini Functions. All rights reserved.
-// SPDX-License-Identifier: Apache-2.0
-// SPDX-License-Identifier: MIT
+// Copyright ยฉ 2023 Common (CMN) library. All rights reserved.
+// SPDX-License-Identifier: Apache-2.0 OR MIT
/// The `serde` crate provides the `Serialize` and `Deserialize` traits
/// that are used to serialize and deserialize the data.
@@ -30,404 +29,580 @@ impl Default for Words {
/// The list of words.
pub const WORD_LIST: &[&str] = &[
- "aboard", "abode", "abort", "abound", "about", "above", "abroad", "abrupt", "absent", "absorb",
- "absurd", "abuse", "accent", "accept", "access", "accord", "accuse", "ace", "ache", "aching",
- "acid", "acidic", "acorn", "acre", "across", "act", "action", "active", "actor", "actual",
- "acute", "adapt", "add", "added", "addict", "adept", "adhere", "adjust", "admire", "admit",
- "adam", "afghan", "alaska", "alice", "allah", "amazon", "andrew", "anglo", "angola", "antony",
- "adobe", "adopt", "adrift", "adult", "adverb", "advert", "aerial", "afar", "affair", "affect",
- "afford", "afield", "afloat", "afraid", "afresh", "after", "again", "age", "agency", "agenda",
- "agent", "aghast", "agile", "ago", "agony", "agree", "agreed", "ahead", "aid", "aide", "aim",
- "air", "airman", "airy", "akin", "alarm", "albeit", "album", "alert", "alibi", "alien",
- "alight", "align", "alike", "alive", "alkali", "all", "alley", "allied", "allow", "alloy",
- "ally", "almond", "almost", "aloft", "alone", "along", "aloof", "aloud", "alpha", "alpine",
- "also", "altar", "alter", "always", "amaze", "amber", "ambush", "amen", "amend", "amid",
- "amidst", "amiss", "among", "amount", "ample", "amuse", "anchor", "and", "anew", "angel",
- "anger", "angle", "angry", "animal", "ankle", "annoy", "annual", "answer", "anthem", "anti",
- "any", "anyhow", "anyway", "apart", "apathy", "apex", "apiece", "appeal", "appear", "apple",
- "apply", "apron", "arcade", "arcane", "arch", "ardent", "are", "area", "argue", "arid",
- "april", "arab", "arctic", "athens", "austin", "bach", "baltic", "basque", "berlin", "bible",
- "arise", "arm", "armful", "armpit", "army", "aroma", "around", "arouse", "array", "arrest",
- "arrive", "arrow", "arson", "art", "artery", "artful", "artist", "ascent", "ashen", "ashore",
- "aside", "ask", "asleep", "aspect", "assay", "assent", "assert", "assess", "asset", "assign",
- "assist", "assume", "assure", "asthma", "astute", "asylum", "ate", "atlas", "atom", "atomic",
- "attach", "attack", "attain", "attend", "attic", "auburn", "audio", "audit", "august", "aunt",
- "auntie", "aura", "author", "auto", "autumn", "avail", "avenge", "avenue", "avert", "avid",
- "avoid", "await", "awake", "awaken", "award", "aware", "awash", "away", "awful", "awhile",
- "axes", "axiom", "axis", "axle", "aye", "babe", "baby", "back", "backup", "bacon", "bad",
- "badge", "badly", "bag", "baggy", "bail", "bait", "bake", "baker", "bakery", "bald", "ball",
- "ballad", "ballet", "ballot", "bamboo", "ban", "banal", "banana", "band", "bang", "bank",
- "bar", "barber", "bare", "barely", "barge", "bark", "barley", "barn", "baron", "barrel",
- "barren", "basalt", "base", "basic", "basil", "basin", "basis", "basket", "bass", "bat",
- "batch", "bath", "baton", "battle", "bay", "beach", "beacon", "beak", "beam", "bean", "bear",
- "beard", "beast", "beat", "beauty", "become", "bed", "beech", "beef", "beefy", "beep", "beer",
- "beet", "beetle", "before", "beggar", "begin", "behalf", "behave", "behind", "beige", "being",
- "belief", "bell", "belly", "belong", "below", "belt", "bench", "bend", "benign", "bent",
- "berry", "berth", "beset", "beside", "best", "bestow", "bet", "beta", "betray", "better",
- "beware", "beyond", "bias", "biceps", "bicker", "bid", "big", "bigger", "bike", "bile", "bill",
- "binary", "bind", "biopsy", "birch", "bird", "birdie", "birth", "bishop", "bit", "bitch",
- "bite", "bitter", "black", "blade", "blame", "bland", "blast", "blaze", "bleak", "blend",
- "bless", "blew", "blind", "blink", "blip", "bliss", "blitz", "block", "blond", "blood",
- "bloody", "bloom", "blot", "blouse", "blow", "blue", "bluff", "blunt", "blur", "blush", "boar",
- "board", "boast", "boat", "bodily", "body", "bogus", "boil", "bold", "bolt", "bomb", "bond",
- "bombay", "bonn", "boston", "brazil", "briton", "buddha", "burma", "caesar", "cairo", "canada",
- "bone", "bonnet", "bonus", "bony", "book", "boom", "boost", "boot", "booth", "booze", "border",
- "bore", "borrow", "bosom", "boss", "both", "bother", "bottle", "bottom", "bought", "bounce",
- "bound", "bounty", "bout", "bovine", "bow", "bowel", "bowl", "box", "boy", "boyish", "brace",
- "brain", "brainy", "brake", "bran", "branch", "brand", "brandy", "brass", "brave", "bravo",
- "breach", "bread", "break", "breast", "breath", "bred", "breed", "breeze", "brew", "brick",
- "bride", "bridge", "brief", "bright", "brim", "brine", "bring", "brink", "brisk", "broad",
- "broke", "broken", "bronze", "brook", "broom", "brown", "bruise", "brush", "brutal", "brute",
- "bubble", "buck", "bucket", "buckle", "budget", "buffet", "buggy", "build", "bulb", "bulge",
- "bulk", "bulky", "bull", "bullet", "bully", "bump", "bumpy", "bunch", "bundle", "bunk",
- "bunny", "burden", "bureau", "burial", "buried", "burly", "burn", "burnt", "burrow", "burst",
- "bury", "bus", "bush", "bust", "bustle", "busy", "but", "butler", "butt", "butter", "button",
- "buy", "buyer", "buzz", "bye", "byte", "cab", "cabin", "cable", "cache", "cactus", "cage",
- "cake", "calf", "call", "caller", "calm", "calmly", "came", "camel", "camera", "camp",
- "campus", "can", "canal", "canary", "cancel", "cancer", "candid", "candle", "candy", "cane",
- "canine", "canoe", "canopy", "canvas", "canyon", "cap", "cape", "car", "carbon", "card",
- "care", "career", "caress", "cargo", "carnal", "carp", "carpet", "carrot", "carry", "cart",
- "carl", "carol", "celtic", "chile", "china", "christ", "congo", "cuba", "cyprus", "czech",
- "cartel", "case", "cash", "cask", "cast", "castle", "casual", "cat", "catch", "cater",
- "cattle", "caught", "causal", "cause", "cave", "cease", "celery", "cell", "cellar", "cement",
- "censor", "census", "cereal", "cervix", "chain", "chair", "chalk", "chalky", "champ", "chance",
- "change", "chant", "chaos", "chap", "chapel", "charge", "charm", "chart", "chase", "chat",
- "cheap", "cheat", "check", "cheek", "cheeky", "cheer", "cheery", "cheese", "chef", "cherry",
- "chess", "chest", "chew", "chic", "chick", "chief", "child", "chill", "chilly", "chin", "chip",
- "choice", "choir", "choose", "chop", "choppy", "chord", "chorus", "chose", "chosen", "chrome",
- "chunk", "chunky", "church", "cider", "cigar", "cinema", "circa", "circle", "circus", "cite",
- "city", "civic", "civil", "clad", "claim", "clammy", "clan", "clap", "clash", "clasp", "class",
- "clause", "claw", "clay", "clean", "clear", "clergy", "clerk", "clever", "click", "client",
- "cliff", "climax", "climb", "clinch", "cling", "clinic", "clip", "cloak", "clock", "clone",
- "close", "closer", "closet", "cloth", "cloud", "cloudy", "clout", "clown", "club", "clue",
- "clumsy", "clung", "clutch", "coach", "coal", "coarse", "coast", "coat", "coax", "cobalt",
- "cobra", "coca", "cock", "cocoa", "code", "coffee", "coffin", "cohort", "coil", "coin", "coke",
- "cold", "collar", "colon", "colony", "colt", "column", "comb", "combat", "come", "comedy",
- "comic", "commit", "common", "compel", "comply", "concur", "cone", "confer", "consul",
- "convex", "convey", "convoy", "cook", "cool", "cope", "copper", "copy", "coral", "cord",
- "core", "cork", "corn", "corner", "corps", "corpse", "corpus", "cortex", "cosmic", "cosmos",
- "cost", "costly", "cosy", "cotton", "couch", "cough", "could", "count", "county", "coup",
- "couple", "coupon", "course", "court", "cousin", "cove", "cover", "covert", "cow", "coward",
- "cowboy", "crab", "crack", "cradle", "craft", "crafty", "crag", "crane", "crap", "crash",
- "crate", "crater", "crawl", "crazy", "creak", "cream", "creamy", "create", "credit", "creed",
- "creek", "creep", "creepy", "crept", "crest", "crew", "cried", "crime", "crisis", "crisp",
- "critic", "croft", "crook", "crop", "cross", "crow", "crowd", "crown", "crude", "cruel",
- "cruise", "crunch", "crush", "crust", "crux", "cry", "crypt", "cube", "cubic", "cuckoo",
- "cuff", "cult", "cup", "curb", "cure", "curfew", "curl", "curry", "curse", "cursor", "curve",
- "custom", "cut", "cute", "cycle", "cyclic", "cynic", "dad", "daddy", "dagger", "daily",
- "dairy", "daisy", "dale", "damage", "damn", "damp", "dampen", "dance", "danger", "dare",
- "dallas", "danish", "darwin", "david", "delhi", "derby", "diana", "dublin", "dutch", "east",
- "dark", "darken", "dash", "data", "date", "dawn", "day", "dead", "deadly", "deaf", "deal",
- "dealer", "dean", "dear", "death", "debate", "debit", "debris", "debt", "debtor", "decade",
- "decay", "decent", "decide", "deck", "decor", "decree", "deduce", "deed", "deep", "deeply",
- "deer", "defeat", "defect", "defend", "defer", "define", "defy", "degree", "deity", "delay",
- "delete", "delta", "demand", "demise", "demo", "demon", "demure", "denial", "denote", "dense",
- "dental", "deny", "depart", "depend", "depict", "deploy", "depot", "depth", "deputy", "derive",
- "desert", "design", "desire", "desist", "desk", "detail", "detect", "deter", "detest",
- "detour", "device", "devil", "devise", "devoid", "devote", "devour", "dial", "diary", "dice",
- "dictum", "did", "die", "diesel", "diet", "differ", "digest", "digit", "dine", "dinghy",
- "dinner", "diode", "dire", "direct", "dirt", "dirty", "disc", "disco", "dish", "disk",
- "dismal", "dispel", "ditch", "dive", "divert", "divide", "divine", "dizzy", "docile", "dock",
- "doctor", "dog", "dogma", "dole", "doll", "dollar", "dolly", "domain", "dome", "domino",
- "donate", "done", "donkey", "donor", "doom", "door", "dorsal", "dose", "double", "doubt",
- "dough", "dour", "dove", "down", "dozen", "draft", "drag", "dragon", "drain", "drama", "drank",
- "draw", "drawer", "dread", "dream", "dreary", "dress", "drew", "dried", "drift", "drill",
- "drink", "drip", "drive", "driver", "drop", "drove", "drown", "drug", "drum", "drunk", "dry",
- "dual", "duck", "duct", "due", "duel", "duet", "duke", "dull", "duly", "dumb", "dummy", "dump",
- "dune", "dung", "duress", "during", "dusk", "dust", "dusty", "duty", "dwarf", "dwell", "dyer",
- "dying", "dynamo", "each", "eager", "eagle", "ear", "earl", "early", "earn", "earth", "ease",
- "easel", "easily", "easter", "easy", "eat", "eaten", "eater", "echo", "eddy", "edge", "edible",
- "eden", "edward", "eric", "essex", "europe", "eve", "exodus", "france", "french", "friday",
- "edict", "edit", "editor", "eerie", "eerily", "effect", "effort", "egg", "ego", "eight",
- "eighth", "eighty", "either", "elbow", "elder", "eldest", "elect", "eleven", "elicit", "elite",
- "else", "elude", "elves", "embark", "emblem", "embryo", "emerge", "emit", "empire", "employ",
- "empty", "enable", "enamel", "end", "endure", "enemy", "energy", "engage", "engine", "enjoy",
- "enlist", "enough", "ensure", "entail", "enter", "entire", "entry", "envoy", "envy", "enzyme",
- "epic", "epoch", "equal", "equate", "equip", "equity", "era", "erase", "erect", "erode",
- "erotic", "errant", "error", "escape", "escort", "essay", "estate", "esteem", "ethic",
- "ethnic", "evade", "even", "event", "ever", "every", "evict", "evil", "evoke", "evolve",
- "exact", "exam", "exceed", "excel", "except", "excess", "excise", "excite", "excuse", "exempt",
- "exert", "exile", "exist", "exit", "exotic", "expand", "expect", "expert", "expire", "export",
- "expose", "extend", "extra", "eye", "eyed", "fabric", "face", "facial", "fact", "factor",
- "fade", "fail", "faint", "fair", "fairly", "fairy", "faith", "fake", "falcon", "fall", "false",
- "falter", "fame", "family", "famine", "famous", "fan", "fancy", "far", "farce", "fare", "farm",
- "farmer", "fast", "fasten", "faster", "fat", "fatal", "fate", "father", "fatty", "fault",
- "faulty", "fauna", "fear", "feast", "feat", "fed", "fee", "feeble", "feed", "feel", "feet",
- "fell", "fellow", "felt", "female", "fence", "fend", "ferry", "fetal", "fetch", "feudal",
- "fever", "few", "fewer", "fiance", "fiasco", "fiddle", "field", "fiend", "fierce", "fiery",
- "fifth", "fifty", "fig", "fight", "figure", "file", "fill", "filled", "filler", "film",
- "filter", "filth", "filthy", "final", "finale", "find", "fine", "finger", "finish", "finite",
- "fire", "firm", "firmly", "first", "fiscal", "fish", "fisher", "fist", "fit", "fitful", "five",
- "fix", "flag", "flair", "flak", "flame", "flank", "flap", "flare", "flash", "flask", "flat",
- "flaw", "fled", "flee", "fleece", "fleet", "flesh", "fleshy", "flew", "flick", "flight",
- "flimsy", "flint", "flirt", "float", "flock", "flood", "floor", "floppy", "flora", "floral",
- "flour", "flow", "flower", "fluent", "fluffy", "fluid", "flung", "flurry", "flush", "flute",
- "flux", "fly", "flyer", "foal", "foam", "focal", "focus", "fog", "foil", "fold", "folk",
- "follow", "folly", "fond", "fondly", "font", "food", "fool", "foot", "for", "forbid", "force",
- "ford", "forest", "forge", "forget", "fork", "form", "formal", "format", "former", "fort",
- "forth", "forty", "forum", "fossil", "foster", "foul", "found", "four", "fourth", "fox",
- "foyer", "frail", "frame", "franc", "frank", "fraud", "free", "freed", "freely", "freer",
- "freeze", "frenzy", "fresh", "friar", "fridge", "fried", "friend", "fright", "fringe", "frock",
- "frog", "from", "front", "frost", "frosty", "frown", "frozen", "frugal", "fruit", "fudge",
- "fuel", "fulfil", "full", "fully", "fun", "fund", "funny", "fur", "furry", "fury", "fuse",
- "fusion", "fuss", "fussy", "futile", "future", "fuzzy", "gadget", "gag", "gain", "gala",
- "galaxy", "gale", "gall", "galley", "gallon", "gallop", "gamble", "game", "gamma", "gang",
- "gandhi", "gaul", "gemini", "geneva", "george", "german", "gloria", "god", "gothic", "greece",
- "gap", "garage", "garden", "garlic", "gas", "gasp", "gate", "gather", "gauge", "gaunt", "gave",
- "gay", "gaze", "gear", "geese", "gender", "gene", "genial", "genius", "genre", "gentle",
- "gently", "gentry", "genus", "get", "ghetto", "ghost", "giant", "gift", "giggle", "gill",
- "gilt", "ginger", "girl", "give", "given", "glad", "glade", "glance", "gland", "glare",
- "glass", "glassy", "gleam", "glee", "glide", "global", "globe", "gloom", "gloomy", "glory",
- "gloss", "glossy", "glove", "glow", "glue", "goal", "goat", "gold", "golden", "golf", "gone",
- "gong", "good", "goose", "gorge", "gory", "gosh", "gospel", "gossip", "got", "govern", "gown",
- "grab", "grace", "grade", "grain", "grand", "grant", "grape", "graph", "grasp", "grass",
- "grassy", "grate", "grave", "gravel", "gravy", "gray", "grease", "greasy", "great", "greed",
- "greedy", "green", "greet", "grew", "grey", "grid", "grief", "grill", "grim", "grin", "grind",
- "greek", "hague", "haiti", "hanoi", "harry", "havana", "hawaii", "hebrew", "henry", "hermes",
- "grip", "grit", "gritty", "groan", "groin", "groom", "groove", "gross", "ground", "group",
- "grove", "grow", "grown", "growth", "grudge", "grunt", "guard", "guess", "guest", "guide",
- "guild", "guilt", "guilty", "guise", "guitar", "gulf", "gully", "gun", "gunman", "guru", "gut",
- "guy", "gypsy", "habit", "hack", "had", "hail", "hair", "hairy", "hale", "half", "hall",
- "halt", "hamlet", "hammer", "hand", "handle", "handy", "hang", "hangar", "happen", "happy",
- "harass", "hard", "harder", "hardly", "hare", "harem", "harm", "harp", "harsh", "has", "hash",
- "hassle", "haste", "hasten", "hasty", "hat", "hatch", "hate", "haul", "haunt", "have", "haven",
- "havoc", "hawk", "hazard", "haze", "hazel", "hazy", "head", "heal", "health", "heap", "hear",
- "heard", "heart", "hearth", "hearty", "heat", "heater", "heaven", "heavy", "heck", "hectic",
- "hedge", "heel", "hefty", "height", "heir", "held", "helium", "helix", "hell", "hello", "helm",
- "helmet", "help", "hemp", "hence", "her", "herald", "herb", "herd", "here", "hereby", "hernia",
- "hero", "heroic", "heroin", "hey", "heyday", "hick", "hidden", "hide", "high", "higher",
- "highly", "hill", "him", "hind", "hint", "hippy", "hire", "his", "hiss", "hit", "hive",
- "hindu", "hitler", "idaho", "inca", "india", "indian", "iowa", "iran", "iraq", "irish",
- "hoard", "hoarse", "hobby", "hockey", "hold", "holder", "hole", "hollow", "holly", "holy",
- "home", "honest", "honey", "hood", "hook", "hope", "horn", "horny", "horrid", "horror",
- "horse", "hose", "host", "hot", "hotel", "hound", "hour", "house", "hover", "how", "huge",
- "hull", "human", "humane", "humble", "humid", "hung", "hunger", "hungry", "hunt", "hurdle",
- "hurl", "hurry", "hurt", "hush", "hut", "hybrid", "hymn", "hyphen", "ice", "icing", "icon",
- "idea", "ideal", "idiom", "idiot", "idle", "idly", "idol", "ignite", "ignore", "ill", "image",
- "immune", "impact", "imply", "import", "impose", "incest", "inch", "income", "incur", "indeed",
- "index", "indoor", "induce", "inept", "inert", "infant", "infect", "infer", "influx", "inform",
- "inject", "injure", "injury", "inlaid", "inland", "inlet", "inmate", "inn", "innate", "inner",
- "input", "insane", "insect", "insert", "inset", "inside", "insist", "insult", "insure",
- "intact", "intake", "intend", "inter", "into", "invade", "invent", "invest", "invite",
- "invoke", "inward", "iron", "ironic", "irony", "island", "isle", "issue", "itch", "item",
- "isaac", "isabel", "islam", "israel", "italy", "ivan", "jack", "jacob", "james", "japan",
- "itself", "ivory", "jacket", "jade", "jaguar", "jail", "jargon", "jaw", "jazz", "jeep", "java",
- "jersey", "jesus", "jewish", "jim", "john", "jordan", "joseph", "judas", "judy", "jelly",
- "jerky", "jest", "jet", "jewel", "job", "jock", "jockey", "join", "joint", "joke", "jolly",
- "jolt", "joy", "joyful", "joyous", "judge", "juice", "juicy", "jumble", "jumbo", "july",
- "june", "kansas", "karl", "kenya", "koran", "korea", "kuwait", "laos", "latin", "leo", "jump",
- "jungle", "junior", "junk", "junta", "jury", "just", "karate", "keel", "keen", "keep",
- "keeper", "kept", "kernel", "kettle", "key", "khaki", "kick", "kid", "kidnap", "kidney",
- "kill", "killer", "kin", "kind", "kindly", "king", "kiss", "kite", "kitten", "knack", "knee",
- "knew", "knife", "knight", "knit", "knob", "knock", "knot", "know", "known", "label", "lace",
- "lack", "lad", "ladder", "laden", "lady", "lagoon", "laity", "lake", "lamb", "lame", "lamp",
- "lance", "land", "lane", "lap", "lapse", "large", "larval", "laser", "last", "latch", "late",
- "lately", "latent", "later", "latest", "latter", "laugh", "launch", "lava", "lavish", "law",
- "lawful", "lawn", "lawyer", "lay", "layer", "layman", "lazy", "lead", "leader", "leaf",
- "leafy", "league", "leak", "leaky", "lean", "leap", "learn", "lease", "leash", "least",
- "leave", "led", "ledge", "left", "leg", "legacy", "legal", "legend", "legion", "lemon", "lend",
- "length", "lens", "lent", "leper", "lesion", "less", "lessen", "lesser", "lesson", "lest",
- "let", "lethal", "letter", "level", "lever", "levy", "lewis", "liable", "liar", "libel",
- "libya", "lima", "lisbon", "liz", "london", "louvre", "lucy", "luther", "madame", "madrid",
- "lice", "lick", "lid", "lie", "lied", "life", "lift", "light", "like", "likely", "limb",
- "lime", "limit", "limp", "line", "linear", "linen", "linger", "link", "lion", "lip", "liquid",
- "liquor", "list", "listen", "lit", "live", "lively", "liver", "lizard", "load", "loaf", "loan",
- "lobby", "lobe", "local", "locate", "lock", "locus", "lodge", "loft", "lofty", "log", "logic",
- "logo", "lone", "lonely", "long", "longer", "look", "loop", "loose", "loosen", "loot", "lord",
- "lorry", "lose", "loss", "lost", "lot", "lotion", "lotus", "loud", "loudly", "lounge", "lousy",
- "love", "lovely", "lover", "low", "lower", "lowest", "loyal", "lucid", "luck", "lucky", "lull",
- "lump", "lumpy", "lunacy", "lunar", "lunch", "lung", "lure", "lurid", "lush", "lust", "lute",
- "luxury", "lying", "lymph", "lynch", "lyric", "macho", "macro", "mad", "madam", "made",
- "mafia", "magic", "magma", "magnet", "magnum", "maid", "maiden", "mail", "main", "mainly",
- "major", "make", "maker", "male", "malice", "mall", "malt", "mammal", "manage", "mane",
- "malta", "maria", "mars", "mary", "maya", "mecca", "mexico", "miami", "mickey", "milan",
- "mania", "manic", "manner", "manor", "mantle", "manual", "manure", "many", "map", "maple",
- "marble", "march", "mare", "margin", "marina", "mark", "market", "marry", "marsh", "martin",
- "martyr", "mask", "mason", "mass", "mast", "master", "match", "mate", "matrix", "matter",
- "mature", "maxim", "may", "maybe", "mayor", "maze", "mead", "meadow", "meal", "mean", "meant",
- "meat", "medal", "media", "median", "medic", "medium", "meet", "mellow", "melody", "melon",
- "melt", "member", "memo", "memory", "menace", "mend", "mental", "mentor", "menu", "mercy",
- "mere", "merely", "merge", "merger", "merit", "merry", "mesh", "mess", "messy", "met", "metal",
- "meter", "method", "methyl", "metric", "metro", "mid", "midday", "middle", "midst", "midway",
- "might", "mighty", "mild", "mildew", "mile", "milk", "milky", "mill", "mimic", "mince", "mind",
- "mine", "mini", "mink", "minor", "mint", "minus", "minute", "mirror", "mirth", "misery",
- "miss", "mist", "misty", "mite", "mix", "moan", "moat", "mobile", "mock", "mode", "model",
- "modem", "modern", "modest", "modify", "module", "moist", "molar", "mole", "molten", "moment",
- "monaco", "monday", "moscow", "moses", "moslem", "mrs", "munich", "muslim", "naples", "nazi",
- "money", "monies", "monk", "monkey", "month", "mood", "moody", "moon", "moor", "moral",
- "morale", "morbid", "more", "morgue", "mortal", "mortar", "mosaic", "mosque", "moss", "most",
- "mostly", "moth", "mother", "motion", "motive", "motor", "mould", "mount", "mourn", "mouse",
- "mouth", "move", "movie", "much", "muck", "mucus", "mud", "muddle", "muddy", "mule", "mummy",
- "murder", "murky", "murmur", "muscle", "museum", "music", "mussel", "must", "mutant", "mute",
- "mutiny", "mutter", "mutton", "mutual", "muzzle", "myopic", "myriad", "myself", "mystic",
- "myth", "nadir", "nail", "naked", "name", "namely", "nape", "napkin", "narrow", "nasal",
- "nasty", "nation", "native", "nature", "nausea", "naval", "nave", "navy", "near", "nearer",
- "nearly", "neat", "neatly", "neck", "need", "needle", "needy", "negate", "neon", "nephew",
- "nepal", "newark", "nile", "nobel", "north", "norway", "ohio", "oscar", "oslo", "oxford",
- "nerve", "nest", "neural", "never", "newly", "next", "nice", "nicely", "niche", "nickel",
- "niece", "night", "nimble", "nine", "ninety", "ninth", "noble", "nobody", "node", "noise",
- "noisy", "non", "none", "noon", "nor", "norm", "normal", "nose", "nosy", "not", "note",
- "notice", "notify", "notion", "nought", "noun", "novel", "novice", "now", "nozzle", "nude",
- "null", "numb", "number", "nurse", "nylon", "nymph", "oak", "oasis", "oath", "obese", "obey",
- "object", "oblige", "oboe", "obtain", "occult", "occupy", "occur", "ocean", "octave", "odd",
- "off", "offend", "offer", "office", "offset", "often", "oil", "oily", "okay", "old", "older",
- "oldest", "olive", "omega", "omen", "omit", "once", "one", "onion", "only", "onset", "onto",
- "onus", "onward", "opaque", "open", "openly", "opera", "opium", "oppose", "optic", "option",
- "oracle", "oral", "orange", "orbit", "orchid", "ordeal", "order", "organ", "orgasm", "orient",
- "origin", "ornate", "orphan", "other", "otter", "ought", "ounce", "our", "out", "outer",
- "output", "outset", "oval", "oven", "over", "overt", "owe", "owing", "owl", "own", "owner",
- "oxide", "oxygen", "oyster", "ozone", "pace", "pack", "packet", "pact", "paddle", "paddy",
- "pagan", "page", "paid", "pain", "paint", "pair", "palace", "pale", "palm", "panel", "panic",
- "panama", "paris", "pascal", "paul", "peking", "peru", "peter", "philip", "poland", "polish",
- "papa", "papal", "paper", "parade", "parcel", "pardon", "parent", "parish", "park", "parody",
- "parrot", "part", "partly", "party", "pass", "past", "paste", "pastel", "pastor", "pastry",
- "pat", "patch", "patent", "path", "patio", "patrol", "patron", "pause", "pave", "pawn", "pay",
- "peace", "peach", "peak", "pear", "pearl", "pedal", "peel", "peer", "pelvic", "pelvis", "pen",
- "penal", "pence", "pencil", "penis", "penny", "people", "pepper", "per", "perch", "peril",
- "period", "perish", "permit", "person", "pest", "petite", "petrol", "petty", "phase", "phone",
- "photo", "phrase", "piano", "pick", "picket", "picnic", "pie", "piece", "pier", "pierce",
- "piety", "pig", "pigeon", "piggy", "pike", "pile", "pill", "pillar", "pillow", "pilot", "pin",
- "pinch", "pine", "pink", "pint", "pious", "pipe", "pirate", "piss", "pistol", "piston", "pit",
- "pitch", "pity", "pivot", "pixel", "pizza", "place", "placid", "plague", "plain", "plan",
- "plane", "planet", "plank", "plant", "plasma", "plate", "play", "player", "plea", "plead",
- "please", "pledge", "plenty", "plenum", "plight", "plot", "ploy", "plug", "plum", "plump",
- "plunge", "plural", "plus", "plush", "pocket", "poem", "poet", "poetic", "poetry", "point",
- "poison", "polar", "pole", "police", "policy", "polite", "poll", "pollen", "polo", "pond",
- "ponder", "pony", "pool", "poor", "poorly", "pop", "pope", "poppy", "pore", "pork", "port",
- "portal", "pose", "posh", "post", "postal", "pot", "potato", "potent", "pouch", "pound",
- "pour", "powder", "power", "praise", "pray", "prayer", "preach", "prefer", "prefix", "press",
- "prague", "quebec", "rex", "rhine", "ritz", "robert", "roman", "rome", "rosa", "russia",
- "pretty", "price", "pride", "priest", "primal", "prime", "prince", "print", "prior", "prism",
- "prison", "privy", "prize", "probe", "profit", "prompt", "prone", "proof", "propel", "proper",
- "prose", "proton", "proud", "prove", "proven", "proxy", "prune", "psalm", "pseudo", "psyche",
- "pub", "public", "puff", "pull", "pulp", "pulpit", "pulsar", "pulse", "pump", "punch",
- "punish", "punk", "pupil", "puppet", "puppy", "pure", "purely", "purge", "purify", "purple",
- "purse", "pursue", "push", "pushy", "pussy", "put", "putt", "puzzle", "quaint", "quake",
- "quarry", "quartz", "quay", "queen", "queer", "query", "quest", "queue", "quick", "quid",
- "quiet", "quilt", "quirk", "quit", "quite", "quiver", "quiz", "quota", "quote", "rabbit",
- "race", "racial", "racism", "rack", "racket", "radar", "radio", "radish", "radius", "raffle",
- "raft", "rage", "raid", "rail", "rain", "rainy", "raise", "rally", "ramp", "random", "range",
- "rank", "ransom", "rape", "rapid", "rare", "rarely", "rarity", "rash", "rat", "rate", "rather",
- "ratify", "ratio", "rattle", "rave", "raven", "raw", "ray", "razor", "reach", "react", "read",
- "reader", "ready", "real", "really", "realm", "reap", "rear", "reason", "rebel", "recall",
- "recent", "recess", "recipe", "reckon", "record", "recoup", "rector", "red", "redeem",
- "reduce", "reed", "reef", "refer", "reform", "refuge", "refuse", "regal", "regard", "regent",
- "regime", "region", "regret", "reign", "reject", "relate", "relax", "relay", "relic", "relief",
- "relish", "rely", "remain", "remark", "remedy", "remind", "remit", "remote", "remove", "renal",
- "render", "rent", "rental", "repair", "repeal", "repeat", "repent", "reply", "report",
- "rescue", "resent", "reside", "resign", "resin", "resist", "resort", "rest", "result",
- "resume", "retail", "retain", "retina", "retire", "return", "reveal", "review", "revise",
- "revive", "revolt", "reward", "rhino", "rhyme", "rhythm", "ribbon", "rice", "rich", "rick",
- "rid", "ride", "rider", "ridge", "rife", "rifle", "rift", "right", "rigid", "ring", "rinse",
- "riot", "ripe", "ripen", "ripple", "rise", "risk", "risky", "rite", "ritual", "rival", "river",
- "road", "roar", "roast", "rob", "robe", "robin", "robot", "robust", "rock", "rocket", "rocky",
- "rod", "rode", "rodent", "rogue", "role", "roll", "roof", "room", "root", "rope", "rose",
- "rosy", "rotate", "rotor", "rotten", "rouge", "rough", "round", "route", "rover", "row",
- "royal", "rubble", "ruby", "rudder", "rude", "rugby", "ruin", "rule", "ruler", "rumble",
- "rump", "run", "rune", "rung", "runway", "rural", "rush", "rust", "rustic", "rusty", "sack",
- "sacred", "sad", "saddle", "sadism", "sadly", "safari", "safe", "safely", "safer", "safety",
- "saga", "sage", "said", "sail", "sailor", "saint", "sake", "salad", "salary", "sale", "saline",
- "sahara", "sam", "saturn", "saudi", "saxon", "scot", "seoul", "somali", "sony", "soviet",
- "saliva", "salmon", "saloon", "salt", "salty", "salute", "same", "sample", "sand", "sandy",
- "sane", "sash", "satan", "satin", "satire", "sauce", "sauna", "savage", "save", "say", "scale",
- "scalp", "scan", "scant", "scar", "scarce", "scare", "scarf", "scary", "scene", "scenic",
- "scent", "school", "scope", "score", "scorn", "scotch", "scout", "scrap", "scream", "screen",
- "screw", "script", "scroll", "scrub", "scum", "sea", "seal", "seam", "seaman", "search",
- "season", "seat", "second", "secret", "sect", "sector", "secure", "see", "seed", "seeing",
- "seek", "seem", "seize", "seldom", "select", "self", "sell", "seller", "semi", "senate",
- "send", "senile", "senior", "sense", "sensor", "sent", "sentry", "sequel", "serene", "serial",
- "series", "sermon", "serum", "serve", "server", "set", "settle", "seven", "severe", "sewage",
- "sex", "sexual", "sexy", "shabby", "shade", "shadow", "shady", "shaft", "shaggy", "shah",
- "shake", "shaky", "shall", "sham", "shame", "shape", "share", "shark", "sharp", "shawl", "she",
- "shear", "sheen", "sheep", "sheer", "sheet", "shelf", "shell", "sherry", "shield", "shift",
- "shine", "shiny", "ship", "shire", "shirt", "shit", "shiver", "shock", "shoe", "shook",
- "shoot", "shop", "shore", "short", "shot", "should", "shout", "show", "shower", "shrank",
- "shrewd", "shrill", "shrimp", "shrine", "shrink", "shrub", "shrug", "shut", "shy", "shyly",
- "sick", "side", "siege", "sigh", "sight", "sigma", "sign", "signal", "silent", "silk",
- "silken", "silky", "sill", "silly", "silver", "simple", "simply", "since", "sinful", "sing",
- "singer", "single", "sink", "sir", "siren", "sister", "sit", "site", "six", "sixth", "sixty",
- "size", "sketch", "skill", "skin", "skinny", "skip", "skirt", "skull", "sky", "slab", "slack",
- "slain", "slam", "slang", "slap", "slate", "slater", "slave", "sleek", "sleep", "sleepy",
- "sleeve", "slice", "slick", "slid", "slide", "slight", "slim", "slimy", "sling", "slip",
- "slit", "slogan", "slope", "sloppy", "slot", "slow", "slowly", "slug", "slum", "slump",
- "smack", "small", "smart", "smash", "smear", "smell", "smelly", "smelt", "smile", "smoke",
- "smoky", "smooth", "smug", "snack", "snail", "snake", "snap", "snatch", "sneak", "snow",
- "snowy", "snug", "soak", "soap", "sober", "soccer", "social", "sock", "socket", "soda",
- "sodden", "sodium", "sofa", "soft", "soften", "softly", "soggy", "soil", "solar", "sold",
- "sole", "solely", "solemn", "solid", "solo", "solve", "some", "son", "sonar", "sonata", "song",
- "sonic", "soon", "sooner", "soot", "soothe", "sordid", "sore", "sorrow", "sorry", "sort",
- "soul", "sound", "soup", "sour", "source", "space", "spade", "span", "spare", "spark", "spain",
- "stalin", "sudan", "suez", "sunday", "sweden", "swiss", "sydney", "syria", "taiwan", "sparse",
- "spasm", "spat", "spate", "speak", "spear", "speech", "speed", "speedy", "spell", "spend",
- "sperm", "sphere", "spice", "spicy", "spider", "spiky", "spill", "spin", "spinal", "spine",
- "spiral", "spirit", "spit", "spite", "splash", "split", "spoil", "spoke", "sponge", "spoon",
- "sport", "spot", "spouse", "spray", "spread", "spree", "spring", "sprint", "spur", "squad",
- "square", "squash", "squat", "squid", "stab", "stable", "stack", "staff", "stage", "stain",
- "stair", "stake", "stale", "stall", "stamp", "stance", "stand", "staple", "star", "starch",
- "stare", "stark", "start", "starve", "state", "static", "statue", "status", "stay", "stead",
- "steady", "steak", "steal", "steam", "steel", "steep", "steer", "stem", "stench", "step",
- "stereo", "stern", "stew", "stick", "sticky", "stiff", "stifle", "stigma", "still", "sting",
- "stint", "stir", "stitch", "stock", "stocky", "stone", "stony", "stool", "stop", "store",
- "storm", "stormy", "story", "stout", "stove", "strain", "strait", "strand", "strap", "strata",
- "straw", "stray", "streak", "stream", "street", "stress", "strict", "stride", "strife",
- "strike", "string", "strip", "strive", "stroke", "stroll", "strong", "stud", "studio", "study",
- "stuff", "stuffy", "stunt", "stupid", "sturdy", "style", "submit", "subtle", "subtly",
- "suburb", "such", "suck", "sudden", "sue", "suffer", "sugar", "suit", "suite", "suitor",
- "sullen", "sultan", "sum", "summer", "summit", "summon", "sun", "sunny", "sunset", "super",
- "superb", "supper", "supple", "supply", "sure", "surely", "surf", "surge", "survey", "suture",
- "swamp", "swan", "swap", "swarm", "sway", "swear", "sweat", "sweaty", "sweep", "sweet",
- "swell", "swift", "swim", "swine", "swing", "swirl", "switch", "sword", "swore", "symbol",
- "synod", "syntax", "syrup", "system", "table", "tablet", "taboo", "tacit", "tackle", "tact",
- "tactic", "tail", "tailor", "take", "tale", "talent", "talk", "tall", "tally", "tame",
- "tandem", "tangle", "tank", "tap", "tape", "target", "tariff", "tart", "task", "taste",
- "tarzan", "taurus", "tehran", "teresa", "texas", "thomas", "tibet", "tokyo", "tom", "turk",
- "tasty", "tattoo", "taut", "tavern", "tax", "taxi", "tea", "teach", "teak", "team", "tear",
- "tease", "tech", "teeth", "tell", "temper", "temple", "tempo", "tempt", "ten", "tenant",
- "tend", "tender", "tendon", "tennis", "tenor", "tense", "tensor", "tent", "tenth", "tenure",
- "term", "terror", "test", "text", "than", "thank", "that", "the", "their", "them", "theme",
- "then", "thence", "theory", "there", "these", "thesis", "they", "thick", "thief", "thigh",
- "thin", "thing", "think", "third", "thirst", "thirty", "this", "thorn", "those", "though",
- "thread", "threat", "three", "thrill", "thrive", "throat", "throne", "throng", "throw",
- "thrust", "thud", "thug", "thumb", "thus", "thyme", "tick", "ticket", "tidal", "tide", "tidy",
- "tie", "tier", "tiger", "tight", "tile", "till", "tilt", "timber", "time", "timid", "tin",
- "tiny", "tip", "tissue", "title", "toad", "toast", "today", "toilet", "token", "told", "toll",
- "tomato", "tomb", "tonal", "tone", "tongue", "tonic", "too", "took", "tool", "tooth", "top",
- "topaz", "topic", "torch", "torque", "torso", "tort", "toss", "total", "touch", "tough",
- "tour", "toward", "towel", "tower", "town", "toxic", "toxin", "trace", "track", "tract",
- "trade", "tragic", "trail", "train", "trait", "tram", "trance", "trap", "trauma", "travel",
- "tray", "tread", "treat", "treaty", "treble", "tree", "trek", "tremor", "trench", "trend",
- "trendy", "trial", "tribal", "tribe", "trick", "tricky", "tried", "trifle", "trim", "trio",
- "trip", "triple", "troop", "trophy", "trot", "trough", "trout", "truce", "truck", "true",
- "truly", "trunk", "trust", "truth", "try", "tsar", "tube", "tumble", "tuna", "tundra", "tune",
- "tung", "tunic", "tunnel", "turban", "turf", "turn", "turtle", "tutor", "tweed", "twelve",
- "turkey", "uganda", "venice", "venus", "vienna", "viking", "virgo", "warsaw", "west", "yale",
- "twenty", "twice", "twin", "twist", "two", "tycoon", "tying", "type", "tyrant", "ugly",
- "ulcer", "ultra", "umpire", "unable", "uncle", "under", "uneasy", "unfair", "unify", "union",
- "unique", "unit", "unite", "unity", "unlike", "unrest", "unruly", "until", "update", "upheld",
- "uphill", "uphold", "upon", "uproar", "upset", "upshot", "uptake", "upturn", "upward", "urban",
- "urge", "urgent", "urging", "urine", "usable", "usage", "use", "useful", "user", "usual",
- "uterus", "utmost", "utter", "vacant", "vacuum", "vagina", "vague", "vain", "valet", "valid",
- "valley", "value", "valve", "van", "vanish", "vanity", "vary", "vase", "vast", "vat", "vault",
- "vector", "veil", "vein", "velvet", "vendor", "veneer", "venom", "vent", "venue", "verb",
- "verbal", "verge", "verify", "verity", "verse", "versus", "very", "vessel", "vest", "veto",
- "via", "viable", "vicar", "vice", "victim", "victor", "video", "view", "vigil", "vile",
- "villa", "vine", "vinyl", "viola", "violet", "violin", "viral", "virgin", "virtue", "virus",
- "visa", "vision", "visit", "visual", "vital", "vivid", "vocal", "vodka", "vogue", "voice",
- "void", "volley", "volume", "vomit", "vote", "vowel", "voyage", "vulgar", "wade", "wage",
- "waist", "wait", "waiter", "wake", "walk", "walker", "wall", "wallet", "walnut", "wander",
- "want", "war", "warden", "warm", "warmth", "warn", "warp", "wary", "was", "wash", "wasp",
- "waste", "watch", "water", "watery", "wave", "way", "weak", "weaken", "wealth", "weapon",
- "wear", "weary", "wedge", "wee", "weed", "week", "weekly", "weep", "weight", "weird", "well",
- "were", "wet", "whale", "wharf", "what", "wheat", "wheel", "when", "whence", "where", "which",
- "whiff", "whig", "while", "whim", "whip", "whisky", "white", "who", "whole", "wholly", "whom",
- "whore", "whose", "why", "wide", "widely", "widen", "wider", "widow", "width", "wife", "wild",
- "wildly", "wilful", "will", "willow", "win", "wind", "window", "windy", "wine", "wing", "wink",
- "winner", "winter", "wipe", "wire", "wisdom", "wise", "wish", "wit", "witch", "with", "within",
- "witty", "wizard", "woke", "wolf", "wolves", "woman", "womb", "won", "wonder", "wood",
- "wooden", "woods", "woody", "wool", "word", "work", "worker", "world", "worm", "worry",
- "worse", "worst", "worth", "worthy", "would", "wound", "wrap", "wrath", "wreath", "wreck",
- "wright", "wrist", "writ", "write", "writer", "wrong", "xerox", "yacht", "yard", "yarn",
- "yeah", "year", "yeast", "yellow", "yet", "yield", "yogurt", "yolk", "you", "young", "your",
- "yemen", "york", "zaire", "zurich", "aback", "abbey", "abbot", "abide", "ablaze", "able",
- "youth", "zeal", "zebra", "zenith", "zero", "zigzag", "zinc", "zombie", "zone",
+ "aboard", "abode", "abort", "abound", "about", "above", "abroad",
+ "abrupt", "absent", "absorb", "absurd", "abuse", "accent",
+ "accept", "access", "accord", "accuse", "ace", "ache", "aching",
+ "acid", "acidic", "acorn", "acre", "across", "act", "action",
+ "active", "actor", "actual", "acute", "adapt", "add", "added",
+ "addict", "adept", "adhere", "adjust", "admire", "admit", "adam",
+ "afghan", "alaska", "alice", "allah", "amazon", "andrew", "anglo",
+ "angola", "antony", "adobe", "adopt", "adrift", "adult", "adverb",
+ "advert", "aerial", "afar", "affair", "affect", "afford", "afield",
+ "afloat", "afraid", "afresh", "after", "again", "age", "agency",
+ "agenda", "agent", "aghast", "agile", "ago", "agony", "agree",
+ "agreed", "ahead", "aid", "aide", "aim", "air", "airman", "airy",
+ "akin", "alarm", "albeit", "album", "alert", "alibi", "alien",
+ "alight", "align", "alike", "alive", "alkali", "all", "alley",
+ "allied", "allow", "alloy", "ally", "almond", "almost", "aloft",
+ "alone", "along", "aloof", "aloud", "alpha", "alpine", "also",
+ "altar", "alter", "always", "amaze", "amber", "ambush", "amen",
+ "amend", "amid", "amidst", "amiss", "among", "amount", "ample",
+ "amuse", "anchor", "and", "anew", "angel", "anger", "angle",
+ "angry", "animal", "ankle", "annoy", "annual", "answer", "anthem",
+ "anti", "any", "anyhow", "anyway", "apart", "apathy", "apex",
+ "apiece", "appeal", "appear", "apple", "apply", "apron", "arcade",
+ "arcane", "arch", "ardent", "are", "area", "argue", "arid",
+ "april", "arab", "arctic", "athens", "austin", "bach", "baltic",
+ "basque", "berlin", "bible", "arise", "arm", "armful", "armpit",
+ "army", "aroma", "around", "arouse", "array", "arrest", "arrive",
+ "arrow", "arson", "art", "artery", "artful", "artist", "ascent",
+ "ashen", "ashore", "aside", "ask", "asleep", "aspect", "assay",
+ "assent", "assert", "assess", "asset", "assign", "assist",
+ "assume", "assure", "asthma", "astute", "asylum", "ate", "atlas",
+ "atom", "atomic", "attach", "attack", "attain", "attend", "attic",
+ "auburn", "audio", "audit", "august", "aunt", "auntie", "aura",
+ "author", "auto", "autumn", "avail", "avenge", "avenue", "avert",
+ "avid", "avoid", "await", "awake", "awaken", "award", "aware",
+ "awash", "away", "awful", "awhile", "axes", "axiom", "axis",
+ "axle", "aye", "babe", "baby", "back", "backup", "bacon", "bad",
+ "badge", "badly", "bag", "baggy", "bail", "bait", "bake", "baker",
+ "bakery", "bald", "ball", "ballad", "ballet", "ballot", "bamboo",
+ "ban", "banal", "banana", "band", "bang", "bank", "bar", "barber",
+ "bare", "barely", "barge", "bark", "barley", "barn", "baron",
+ "barrel", "barren", "basalt", "base", "basic", "basil", "basin",
+ "basis", "basket", "bass", "bat", "batch", "bath", "baton",
+ "battle", "bay", "beach", "beacon", "beak", "beam", "bean", "bear",
+ "beard", "beast", "beat", "beauty", "become", "bed", "beech",
+ "beef", "beefy", "beep", "beer", "beet", "beetle", "before",
+ "beggar", "begin", "behalf", "behave", "behind", "beige", "being",
+ "belief", "bell", "belly", "belong", "below", "belt", "bench",
+ "bend", "benign", "bent", "berry", "berth", "beset", "beside",
+ "best", "bestow", "bet", "beta", "betray", "better", "beware",
+ "beyond", "bias", "biceps", "bicker", "bid", "big", "bigger",
+ "bike", "bile", "bill", "binary", "bind", "biopsy", "birch",
+ "bird", "birdie", "birth", "bishop", "bit", "bitch", "bite",
+ "bitter", "black", "blade", "blame", "bland", "blast", "blaze",
+ "bleak", "blend", "bless", "blew", "blind", "blink", "blip",
+ "bliss", "blitz", "block", "blond", "blood", "bloody", "bloom",
+ "blot", "blouse", "blow", "blue", "bluff", "blunt", "blur",
+ "blush", "boar", "board", "boast", "boat", "bodily", "body",
+ "bogus", "boil", "bold", "bolt", "bomb", "bond", "bombay", "bonn",
+ "boston", "brazil", "briton", "buddha", "burma", "caesar", "cairo",
+ "canada", "bone", "bonnet", "bonus", "bony", "book", "boom",
+ "boost", "boot", "booth", "booze", "border", "bore", "borrow",
+ "bosom", "boss", "both", "bother", "bottle", "bottom", "bought",
+ "bounce", "bound", "bounty", "bout", "bovine", "bow", "bowel",
+ "bowl", "box", "boy", "boyish", "brace", "brain", "brainy",
+ "brake", "bran", "branch", "brand", "brandy", "brass", "brave",
+ "bravo", "breach", "bread", "break", "breast", "breath", "bred",
+ "breed", "breeze", "brew", "brick", "bride", "bridge", "brief",
+ "bright", "brim", "brine", "bring", "brink", "brisk", "broad",
+ "broke", "broken", "bronze", "brook", "broom", "brown", "bruise",
+ "brush", "brutal", "brute", "bubble", "buck", "bucket", "buckle",
+ "budget", "buffet", "buggy", "build", "bulb", "bulge", "bulk",
+ "bulky", "bull", "bullet", "bully", "bump", "bumpy", "bunch",
+ "bundle", "bunk", "bunny", "burden", "bureau", "burial", "buried",
+ "burly", "burn", "burnt", "burrow", "burst", "bury", "bus", "bush",
+ "bust", "bustle", "busy", "but", "butler", "butt", "butter",
+ "button", "buy", "buyer", "buzz", "bye", "byte", "cab", "cabin",
+ "cable", "cache", "cactus", "cage", "cake", "calf", "call",
+ "caller", "calm", "calmly", "came", "camel", "camera", "camp",
+ "campus", "can", "canal", "canary", "cancel", "cancer", "candid",
+ "candle", "candy", "cane", "canine", "canoe", "canopy", "canvas",
+ "canyon", "cap", "cape", "car", "carbon", "card", "care", "career",
+ "caress", "cargo", "carnal", "carp", "carpet", "carrot", "carry",
+ "cart", "carl", "carol", "celtic", "chile", "china", "christ",
+ "congo", "cuba", "cyprus", "czech", "cartel", "case", "cash",
+ "cask", "cast", "castle", "casual", "cat", "catch", "cater",
+ "cattle", "caught", "causal", "cause", "cave", "cease", "celery",
+ "cell", "cellar", "cement", "censor", "census", "cereal", "cervix",
+ "chain", "chair", "chalk", "chalky", "champ", "chance", "change",
+ "chant", "chaos", "chap", "chapel", "charge", "charm", "chart",
+ "chase", "chat", "cheap", "cheat", "check", "cheek", "cheeky",
+ "cheer", "cheery", "cheese", "chef", "cherry", "chess", "chest",
+ "chew", "chic", "chick", "chief", "child", "chill", "chilly",
+ "chin", "chip", "choice", "choir", "choose", "chop", "choppy",
+ "chord", "chorus", "chose", "chosen", "chrome", "chunk", "chunky",
+ "church", "cider", "cigar", "cinema", "circa", "circle", "circus",
+ "cite", "city", "civic", "civil", "clad", "claim", "clammy",
+ "clan", "clap", "clash", "clasp", "class", "clause", "claw",
+ "clay", "clean", "clear", "clergy", "clerk", "clever", "click",
+ "client", "cliff", "climax", "climb", "clinch", "cling", "clinic",
+ "clip", "cloak", "clock", "clone", "close", "closer", "closet",
+ "cloth", "cloud", "cloudy", "clout", "clown", "club", "clue",
+ "clumsy", "clung", "clutch", "coach", "coal", "coarse", "coast",
+ "coat", "coax", "cobalt", "cobra", "coca", "cock", "cocoa", "code",
+ "coffee", "coffin", "cohort", "coil", "coin", "coke", "cold",
+ "collar", "colon", "colony", "colt", "column", "comb", "combat",
+ "come", "comedy", "comic", "commit", "common", "compel", "comply",
+ "concur", "cone", "confer", "consul", "convex", "convey", "convoy",
+ "cook", "cool", "cope", "copper", "copy", "coral", "cord", "core",
+ "cork", "corn", "corner", "corps", "corpse", "corpus", "cortex",
+ "cosmic", "cosmos", "cost", "costly", "cosy", "cotton", "couch",
+ "cough", "could", "count", "county", "coup", "couple", "coupon",
+ "course", "court", "cousin", "cove", "cover", "covert", "cow",
+ "coward", "cowboy", "crab", "crack", "cradle", "craft", "crafty",
+ "crag", "crane", "crap", "crash", "crate", "crater", "crawl",
+ "crazy", "creak", "cream", "creamy", "create", "credit", "creed",
+ "creek", "creep", "creepy", "crept", "crest", "crew", "cried",
+ "crime", "crisis", "crisp", "critic", "croft", "crook", "crop",
+ "cross", "crow", "crowd", "crown", "crude", "cruel", "cruise",
+ "crunch", "crush", "crust", "crux", "cry", "crypt", "cube",
+ "cubic", "cuckoo", "cuff", "cult", "cup", "curb", "cure", "curfew",
+ "curl", "curry", "curse", "cursor", "curve", "custom", "cut",
+ "cute", "cycle", "cyclic", "cynic", "dad", "daddy", "dagger",
+ "daily", "dairy", "daisy", "dale", "damage", "damn", "damp",
+ "dampen", "dance", "danger", "dare", "dallas", "danish", "darwin",
+ "david", "delhi", "derby", "diana", "dublin", "dutch", "east",
+ "dark", "darken", "dash", "data", "date", "dawn", "day", "dead",
+ "deadly", "deaf", "deal", "dealer", "dean", "dear", "death",
+ "debate", "debit", "debris", "debt", "debtor", "decade", "decay",
+ "decent", "decide", "deck", "decor", "decree", "deduce", "deed",
+ "deep", "deeply", "deer", "defeat", "defect", "defend", "defer",
+ "define", "defy", "degree", "deity", "delay", "delete", "delta",
+ "demand", "demise", "demo", "demon", "demure", "denial", "denote",
+ "dense", "dental", "deny", "depart", "depend", "depict", "deploy",
+ "depot", "depth", "deputy", "derive", "desert", "design", "desire",
+ "desist", "desk", "detail", "detect", "deter", "detest", "detour",
+ "device", "devil", "devise", "devoid", "devote", "devour", "dial",
+ "diary", "dice", "dictum", "did", "die", "diesel", "diet",
+ "differ", "digest", "digit", "dine", "dinghy", "dinner", "diode",
+ "dire", "direct", "dirt", "dirty", "disc", "disco", "dish", "disk",
+ "dismal", "dispel", "ditch", "dive", "divert", "divide", "divine",
+ "dizzy", "docile", "dock", "doctor", "dog", "dogma", "dole",
+ "doll", "dollar", "dolly", "domain", "dome", "domino", "donate",
+ "done", "donkey", "donor", "doom", "door", "dorsal", "dose",
+ "double", "doubt", "dough", "dour", "dove", "down", "dozen",
+ "draft", "drag", "dragon", "drain", "drama", "drank", "draw",
+ "drawer", "dread", "dream", "dreary", "dress", "drew", "dried",
+ "drift", "drill", "drink", "drip", "drive", "driver", "drop",
+ "drove", "drown", "drug", "drum", "drunk", "dry", "dual", "duck",
+ "duct", "due", "duel", "duet", "duke", "dull", "duly", "dumb",
+ "dummy", "dump", "dune", "dung", "duress", "during", "dusk",
+ "dust", "dusty", "duty", "dwarf", "dwell", "dyer", "dying",
+ "dynamo", "each", "eager", "eagle", "ear", "earl", "early", "earn",
+ "earth", "ease", "easel", "easily", "easter", "easy", "eat",
+ "eaten", "eater", "echo", "eddy", "edge", "edible", "eden",
+ "edward", "eric", "essex", "europe", "eve", "exodus", "france",
+ "french", "friday", "edict", "edit", "editor", "eerie", "eerily",
+ "effect", "effort", "egg", "ego", "eight", "eighth", "eighty",
+ "either", "elbow", "elder", "eldest", "elect", "eleven", "elicit",
+ "elite", "else", "elude", "elves", "embark", "emblem", "embryo",
+ "emerge", "emit", "empire", "employ", "empty", "enable", "enamel",
+ "end", "endure", "enemy", "energy", "engage", "engine", "enjoy",
+ "enlist", "enough", "ensure", "entail", "enter", "entire", "entry",
+ "envoy", "envy", "enzyme", "epic", "epoch", "equal", "equate",
+ "equip", "equity", "era", "erase", "erect", "erode", "erotic",
+ "errant", "error", "escape", "escort", "essay", "estate", "esteem",
+ "ethic", "ethnic", "evade", "even", "event", "ever", "every",
+ "evict", "evil", "evoke", "evolve", "exact", "exam", "exceed",
+ "excel", "except", "excess", "excise", "excite", "excuse",
+ "exempt", "exert", "exile", "exist", "exit", "exotic", "expand",
+ "expect", "expert", "expire", "export", "expose", "extend",
+ "extra", "eye", "eyed", "fabric", "face", "facial", "fact",
+ "factor", "fade", "fail", "faint", "fair", "fairly", "fairy",
+ "faith", "fake", "falcon", "fall", "false", "falter", "fame",
+ "family", "famine", "famous", "fan", "fancy", "far", "farce",
+ "fare", "farm", "farmer", "fast", "fasten", "faster", "fat",
+ "fatal", "fate", "father", "fatty", "fault", "faulty", "fauna",
+ "fear", "feast", "feat", "fed", "fee", "feeble", "feed", "feel",
+ "feet", "fell", "fellow", "felt", "female", "fence", "fend",
+ "ferry", "fetal", "fetch", "feudal", "fever", "few", "fewer",
+ "fiance", "fiasco", "fiddle", "field", "fiend", "fierce", "fiery",
+ "fifth", "fifty", "fig", "fight", "figure", "file", "fill",
+ "filled", "filler", "film", "filter", "filth", "filthy", "final",
+ "finale", "find", "fine", "finger", "finish", "finite", "fire",
+ "firm", "firmly", "first", "fiscal", "fish", "fisher", "fist",
+ "fit", "fitful", "five", "fix", "flag", "flair", "flak", "flame",
+ "flank", "flap", "flare", "flash", "flask", "flat", "flaw", "fled",
+ "flee", "fleece", "fleet", "flesh", "fleshy", "flew", "flick",
+ "flight", "flimsy", "flint", "flirt", "float", "flock", "flood",
+ "floor", "floppy", "flora", "floral", "flour", "flow", "flower",
+ "fluent", "fluffy", "fluid", "flung", "flurry", "flush", "flute",
+ "flux", "fly", "flyer", "foal", "foam", "focal", "focus", "fog",
+ "foil", "fold", "folk", "follow", "folly", "fond", "fondly",
+ "font", "food", "fool", "foot", "for", "forbid", "force", "ford",
+ "forest", "forge", "forget", "fork", "form", "formal", "format",
+ "former", "fort", "forth", "forty", "forum", "fossil", "foster",
+ "foul", "found", "four", "fourth", "fox", "foyer", "frail",
+ "frame", "franc", "frank", "fraud", "free", "freed", "freely",
+ "freer", "freeze", "frenzy", "fresh", "friar", "fridge", "fried",
+ "friend", "fright", "fringe", "frock", "frog", "from", "front",
+ "frost", "frosty", "frown", "frozen", "frugal", "fruit", "fudge",
+ "fuel", "fulfil", "full", "fully", "fun", "fund", "funny", "fur",
+ "furry", "fury", "fuse", "fusion", "fuss", "fussy", "futile",
+ "future", "fuzzy", "gadget", "gag", "gain", "gala", "galaxy",
+ "gale", "gall", "galley", "gallon", "gallop", "gamble", "game",
+ "gamma", "gang", "gandhi", "gaul", "gemini", "geneva", "george",
+ "german", "gloria", "god", "gothic", "greece", "gap", "garage",
+ "garden", "garlic", "gas", "gasp", "gate", "gather", "gauge",
+ "gaunt", "gave", "gay", "gaze", "gear", "geese", "gender", "gene",
+ "genial", "genius", "genre", "gentle", "gently", "gentry", "genus",
+ "get", "ghetto", "ghost", "giant", "gift", "giggle", "gill",
+ "gilt", "ginger", "girl", "give", "given", "glad", "glade",
+ "glance", "gland", "glare", "glass", "glassy", "gleam", "glee",
+ "glide", "global", "globe", "gloom", "gloomy", "glory", "gloss",
+ "glossy", "glove", "glow", "glue", "goal", "goat", "gold",
+ "golden", "golf", "gone", "gong", "good", "goose", "gorge", "gory",
+ "gosh", "gospel", "gossip", "got", "govern", "gown", "grab",
+ "grace", "grade", "grain", "grand", "grant", "grape", "graph",
+ "grasp", "grass", "grassy", "grate", "grave", "gravel", "gravy",
+ "gray", "grease", "greasy", "great", "greed", "greedy", "green",
+ "greet", "grew", "grey", "grid", "grief", "grill", "grim", "grin",
+ "grind", "greek", "hague", "haiti", "hanoi", "harry", "havana",
+ "hawaii", "hebrew", "henry", "hermes", "grip", "grit", "gritty",
+ "groan", "groin", "groom", "groove", "gross", "ground", "group",
+ "grove", "grow", "grown", "growth", "grudge", "grunt", "guard",
+ "guess", "guest", "guide", "guild", "guilt", "guilty", "guise",
+ "guitar", "gulf", "gully", "gun", "gunman", "guru", "gut", "guy",
+ "gypsy", "habit", "hack", "had", "hail", "hair", "hairy", "hale",
+ "half", "hall", "halt", "hamlet", "hammer", "hand", "handle",
+ "handy", "hang", "hangar", "happen", "happy", "harass", "hard",
+ "harder", "hardly", "hare", "harem", "harm", "harp", "harsh",
+ "has", "hash", "hassle", "haste", "hasten", "hasty", "hat",
+ "hatch", "hate", "haul", "haunt", "have", "haven", "havoc", "hawk",
+ "hazard", "haze", "hazel", "hazy", "head", "heal", "health",
+ "heap", "hear", "heard", "heart", "hearth", "hearty", "heat",
+ "heater", "heaven", "heavy", "heck", "hectic", "hedge", "heel",
+ "hefty", "height", "heir", "held", "helium", "helix", "hell",
+ "hello", "helm", "helmet", "help", "hemp", "hence", "her",
+ "herald", "herb", "herd", "here", "hereby", "hernia", "hero",
+ "heroic", "heroin", "hey", "heyday", "hick", "hidden", "hide",
+ "high", "higher", "highly", "hill", "him", "hind", "hint", "hippy",
+ "hire", "his", "hiss", "hit", "hive", "hindu", "hitler", "idaho",
+ "inca", "india", "indian", "iowa", "iran", "iraq", "irish",
+ "hoard", "hoarse", "hobby", "hockey", "hold", "holder", "hole",
+ "hollow", "holly", "holy", "home", "honest", "honey", "hood",
+ "hook", "hope", "horn", "horny", "horrid", "horror", "horse",
+ "hose", "host", "hot", "hotel", "hound", "hour", "house", "hover",
+ "how", "huge", "hull", "human", "humane", "humble", "humid",
+ "hung", "hunger", "hungry", "hunt", "hurdle", "hurl", "hurry",
+ "hurt", "hush", "hut", "hybrid", "hymn", "hyphen", "ice", "icing",
+ "icon", "idea", "ideal", "idiom", "idiot", "idle", "idly", "idol",
+ "ignite", "ignore", "ill", "image", "immune", "impact", "imply",
+ "import", "impose", "incest", "inch", "income", "incur", "indeed",
+ "index", "indoor", "induce", "inept", "inert", "infant", "infect",
+ "infer", "influx", "inform", "inject", "injure", "injury",
+ "inlaid", "inland", "inlet", "inmate", "inn", "innate", "inner",
+ "input", "insane", "insect", "insert", "inset", "inside", "insist",
+ "insult", "insure", "intact", "intake", "intend", "inter", "into",
+ "invade", "invent", "invest", "invite", "invoke", "inward", "iron",
+ "ironic", "irony", "island", "isle", "issue", "itch", "item",
+ "isaac", "isabel", "islam", "israel", "italy", "ivan", "jack",
+ "jacob", "james", "japan", "itself", "ivory", "jacket", "jade",
+ "jaguar", "jail", "jargon", "jaw", "jazz", "jeep", "java",
+ "jersey", "jesus", "jewish", "jim", "john", "jordan", "joseph",
+ "judas", "judy", "jelly", "jerky", "jest", "jet", "jewel", "job",
+ "jock", "jockey", "join", "joint", "joke", "jolly", "jolt", "joy",
+ "joyful", "joyous", "judge", "juice", "juicy", "jumble", "jumbo",
+ "july", "june", "kansas", "karl", "kenya", "koran", "korea",
+ "kuwait", "laos", "latin", "leo", "jump", "jungle", "junior",
+ "junk", "junta", "jury", "just", "karate", "keel", "keen", "keep",
+ "keeper", "kept", "kernel", "kettle", "key", "khaki", "kick",
+ "kid", "kidnap", "kidney", "kill", "killer", "kin", "kind",
+ "kindly", "king", "kiss", "kite", "kitten", "knack", "knee",
+ "knew", "knife", "knight", "knit", "knob", "knock", "knot", "know",
+ "known", "label", "lace", "lack", "lad", "ladder", "laden", "lady",
+ "lagoon", "laity", "lake", "lamb", "lame", "lamp", "lance", "land",
+ "lane", "lap", "lapse", "large", "larval", "laser", "last",
+ "latch", "late", "lately", "latent", "later", "latest", "latter",
+ "laugh", "launch", "lava", "lavish", "law", "lawful", "lawn",
+ "lawyer", "lay", "layer", "layman", "lazy", "lead", "leader",
+ "leaf", "leafy", "league", "leak", "leaky", "lean", "leap",
+ "learn", "lease", "leash", "least", "leave", "led", "ledge",
+ "left", "leg", "legacy", "legal", "legend", "legion", "lemon",
+ "lend", "length", "lens", "lent", "leper", "lesion", "less",
+ "lessen", "lesser", "lesson", "lest", "let", "lethal", "letter",
+ "level", "lever", "levy", "lewis", "liable", "liar", "libel",
+ "libya", "lima", "lisbon", "liz", "london", "louvre", "lucy",
+ "luther", "madame", "madrid", "lice", "lick", "lid", "lie", "lied",
+ "life", "lift", "light", "like", "likely", "limb", "lime", "limit",
+ "limp", "line", "linear", "linen", "linger", "link", "lion", "lip",
+ "liquid", "liquor", "list", "listen", "lit", "live", "lively",
+ "liver", "lizard", "load", "loaf", "loan", "lobby", "lobe",
+ "local", "locate", "lock", "locus", "lodge", "loft", "lofty",
+ "log", "logic", "logo", "lone", "lonely", "long", "longer", "look",
+ "loop", "loose", "loosen", "loot", "lord", "lorry", "lose", "loss",
+ "lost", "lot", "lotion", "lotus", "loud", "loudly", "lounge",
+ "lousy", "love", "lovely", "lover", "low", "lower", "lowest",
+ "loyal", "lucid", "luck", "lucky", "lull", "lump", "lumpy",
+ "lunacy", "lunar", "lunch", "lung", "lure", "lurid", "lush",
+ "lust", "lute", "luxury", "lying", "lymph", "lynch", "lyric",
+ "macho", "macro", "mad", "madam", "made", "mafia", "magic",
+ "magma", "magnet", "magnum", "maid", "maiden", "mail", "main",
+ "mainly", "major", "make", "maker", "male", "malice", "mall",
+ "malt", "mammal", "manage", "mane", "malta", "maria", "mars",
+ "mary", "maya", "mecca", "mexico", "miami", "mickey", "milan",
+ "mania", "manic", "manner", "manor", "mantle", "manual", "manure",
+ "many", "map", "maple", "marble", "march", "mare", "margin",
+ "marina", "mark", "market", "marry", "marsh", "martin", "martyr",
+ "mask", "mason", "mass", "mast", "master", "match", "mate",
+ "matrix", "matter", "mature", "maxim", "may", "maybe", "mayor",
+ "maze", "mead", "meadow", "meal", "mean", "meant", "meat", "medal",
+ "media", "median", "medic", "medium", "meet", "mellow", "melody",
+ "melon", "melt", "member", "memo", "memory", "menace", "mend",
+ "mental", "mentor", "menu", "mercy", "mere", "merely", "merge",
+ "merger", "merit", "merry", "mesh", "mess", "messy", "met",
+ "metal", "meter", "method", "methyl", "metric", "metro", "mid",
+ "midday", "middle", "midst", "midway", "might", "mighty", "mild",
+ "mildew", "mile", "milk", "milky", "mill", "mimic", "mince",
+ "mind", "mine", "mini", "mink", "minor", "mint", "minus", "minute",
+ "mirror", "mirth", "misery", "miss", "mist", "misty", "mite",
+ "mix", "moan", "moat", "mobile", "mock", "mode", "model", "modem",
+ "modern", "modest", "modify", "module", "moist", "molar", "mole",
+ "molten", "moment", "monaco", "monday", "moscow", "moses",
+ "moslem", "mrs", "munich", "muslim", "naples", "nazi", "money",
+ "monies", "monk", "monkey", "month", "mood", "moody", "moon",
+ "moor", "moral", "morale", "morbid", "more", "morgue", "mortal",
+ "mortar", "mosaic", "mosque", "moss", "most", "mostly", "moth",
+ "mother", "motion", "motive", "motor", "mould", "mount", "mourn",
+ "mouse", "mouth", "move", "movie", "much", "muck", "mucus", "mud",
+ "muddle", "muddy", "mule", "mummy", "murder", "murky", "murmur",
+ "muscle", "museum", "music", "mussel", "must", "mutant", "mute",
+ "mutiny", "mutter", "mutton", "mutual", "muzzle", "myopic",
+ "myriad", "myself", "mystic", "myth", "nadir", "nail", "naked",
+ "name", "namely", "nape", "napkin", "narrow", "nasal", "nasty",
+ "nation", "native", "nature", "nausea", "naval", "nave", "navy",
+ "near", "nearer", "nearly", "neat", "neatly", "neck", "need",
+ "needle", "needy", "negate", "neon", "nephew", "nepal", "newark",
+ "nile", "nobel", "north", "norway", "ohio", "oscar", "oslo",
+ "oxford", "nerve", "nest", "neural", "never", "newly", "next",
+ "nice", "nicely", "niche", "nickel", "niece", "night", "nimble",
+ "nine", "ninety", "ninth", "noble", "nobody", "node", "noise",
+ "noisy", "non", "none", "noon", "nor", "norm", "normal", "nose",
+ "nosy", "not", "note", "notice", "notify", "notion", "nought",
+ "noun", "novel", "novice", "now", "nozzle", "nude", "null", "numb",
+ "number", "nurse", "nylon", "nymph", "oak", "oasis", "oath",
+ "obese", "obey", "object", "oblige", "oboe", "obtain", "occult",
+ "occupy", "occur", "ocean", "octave", "odd", "off", "offend",
+ "offer", "office", "offset", "often", "oil", "oily", "okay", "old",
+ "older", "oldest", "olive", "omega", "omen", "omit", "once", "one",
+ "onion", "only", "onset", "onto", "onus", "onward", "opaque",
+ "open", "openly", "opera", "opium", "oppose", "optic", "option",
+ "oracle", "oral", "orange", "orbit", "orchid", "ordeal", "order",
+ "organ", "orgasm", "orient", "origin", "ornate", "orphan", "other",
+ "otter", "ought", "ounce", "our", "out", "outer", "output",
+ "outset", "oval", "oven", "over", "overt", "owe", "owing", "owl",
+ "own", "owner", "oxide", "oxygen", "oyster", "ozone", "pace",
+ "pack", "packet", "pact", "paddle", "paddy", "pagan", "page",
+ "paid", "pain", "paint", "pair", "palace", "pale", "palm", "panel",
+ "panic", "panama", "paris", "pascal", "paul", "peking", "peru",
+ "peter", "philip", "poland", "polish", "papa", "papal", "paper",
+ "parade", "parcel", "pardon", "parent", "parish", "park", "parody",
+ "parrot", "part", "partly", "party", "pass", "past", "paste",
+ "pastel", "pastor", "pastry", "pat", "patch", "patent", "path",
+ "patio", "patrol", "patron", "pause", "pave", "pawn", "pay",
+ "peace", "peach", "peak", "pear", "pearl", "pedal", "peel", "peer",
+ "pelvic", "pelvis", "pen", "penal", "pence", "pencil", "penis",
+ "penny", "people", "pepper", "per", "perch", "peril", "period",
+ "perish", "permit", "person", "pest", "petite", "petrol", "petty",
+ "phase", "phone", "photo", "phrase", "piano", "pick", "picket",
+ "picnic", "pie", "piece", "pier", "pierce", "piety", "pig",
+ "pigeon", "piggy", "pike", "pile", "pill", "pillar", "pillow",
+ "pilot", "pin", "pinch", "pine", "pink", "pint", "pious", "pipe",
+ "pirate", "piss", "pistol", "piston", "pit", "pitch", "pity",
+ "pivot", "pixel", "pizza", "place", "placid", "plague", "plain",
+ "plan", "plane", "planet", "plank", "plant", "plasma", "plate",
+ "play", "player", "plea", "plead", "please", "pledge", "plenty",
+ "plenum", "plight", "plot", "ploy", "plug", "plum", "plump",
+ "plunge", "plural", "plus", "plush", "pocket", "poem", "poet",
+ "poetic", "poetry", "point", "poison", "polar", "pole", "police",
+ "policy", "polite", "poll", "pollen", "polo", "pond", "ponder",
+ "pony", "pool", "poor", "poorly", "pop", "pope", "poppy", "pore",
+ "pork", "port", "portal", "pose", "posh", "post", "postal", "pot",
+ "potato", "potent", "pouch", "pound", "pour", "powder", "power",
+ "praise", "pray", "prayer", "preach", "prefer", "prefix", "press",
+ "prague", "quebec", "rex", "rhine", "ritz", "robert", "roman",
+ "rome", "rosa", "russia", "pretty", "price", "pride", "priest",
+ "primal", "prime", "prince", "print", "prior", "prism", "prison",
+ "privy", "prize", "probe", "profit", "prompt", "prone", "proof",
+ "propel", "proper", "prose", "proton", "proud", "prove", "proven",
+ "proxy", "prune", "psalm", "pseudo", "psyche", "pub", "public",
+ "puff", "pull", "pulp", "pulpit", "pulsar", "pulse", "pump",
+ "punch", "punish", "punk", "pupil", "puppet", "puppy", "pure",
+ "purely", "purge", "purify", "purple", "purse", "pursue", "push",
+ "pushy", "pussy", "put", "putt", "puzzle", "quaint", "quake",
+ "quarry", "quartz", "quay", "queen", "queer", "query", "quest",
+ "queue", "quick", "quid", "quiet", "quilt", "quirk", "quit",
+ "quite", "quiver", "quiz", "quota", "quote", "rabbit", "race",
+ "racial", "racism", "rack", "racket", "radar", "radio", "radish",
+ "radius", "raffle", "raft", "rage", "raid", "rail", "rain",
+ "rainy", "raise", "rally", "ramp", "random", "range", "rank",
+ "ransom", "rape", "rapid", "rare", "rarely", "rarity", "rash",
+ "rat", "rate", "rather", "ratify", "ratio", "rattle", "rave",
+ "raven", "raw", "ray", "razor", "reach", "react", "read", "reader",
+ "ready", "real", "really", "realm", "reap", "rear", "reason",
+ "rebel", "recall", "recent", "recess", "recipe", "reckon",
+ "record", "recoup", "rector", "red", "redeem", "reduce", "reed",
+ "reef", "refer", "reform", "refuge", "refuse", "regal", "regard",
+ "regent", "regime", "region", "regret", "reign", "reject",
+ "relate", "relax", "relay", "relic", "relief", "relish", "rely",
+ "remain", "remark", "remedy", "remind", "remit", "remote",
+ "remove", "renal", "render", "rent", "rental", "repair", "repeal",
+ "repeat", "repent", "reply", "report", "rescue", "resent",
+ "reside", "resign", "resin", "resist", "resort", "rest", "result",
+ "resume", "retail", "retain", "retina", "retire", "return",
+ "reveal", "review", "revise", "revive", "revolt", "reward",
+ "rhino", "rhyme", "rhythm", "ribbon", "rice", "rich", "rick",
+ "rid", "ride", "rider", "ridge", "rife", "rifle", "rift", "right",
+ "rigid", "ring", "rinse", "riot", "ripe", "ripen", "ripple",
+ "rise", "risk", "risky", "rite", "ritual", "rival", "river",
+ "road", "roar", "roast", "rob", "robe", "robin", "robot", "robust",
+ "rock", "rocket", "rocky", "rod", "rode", "rodent", "rogue",
+ "role", "roll", "roof", "room", "root", "rope", "rose", "rosy",
+ "rotate", "rotor", "rotten", "rouge", "rough", "round", "route",
+ "rover", "row", "royal", "rubble", "ruby", "rudder", "rude",
+ "rugby", "ruin", "rule", "ruler", "rumble", "rump", "run", "rune",
+ "rung", "runway", "rural", "rush", "rust", "rustic", "rusty",
+ "sack", "sacred", "sad", "saddle", "sadism", "sadly", "safari",
+ "safe", "safely", "safer", "safety", "saga", "sage", "said",
+ "sail", "sailor", "saint", "sake", "salad", "salary", "sale",
+ "saline", "sahara", "sam", "saturn", "saudi", "saxon", "scot",
+ "seoul", "somali", "sony", "soviet", "saliva", "salmon", "saloon",
+ "salt", "salty", "salute", "same", "sample", "sand", "sandy",
+ "sane", "sash", "satan", "satin", "satire", "sauce", "sauna",
+ "savage", "save", "say", "scale", "scalp", "scan", "scant", "scar",
+ "scarce", "scare", "scarf", "scary", "scene", "scenic", "scent",
+ "school", "scope", "score", "scorn", "scotch", "scout", "scrap",
+ "scream", "screen", "screw", "script", "scroll", "scrub", "scum",
+ "sea", "seal", "seam", "seaman", "search", "season", "seat",
+ "second", "secret", "sect", "sector", "secure", "see", "seed",
+ "seeing", "seek", "seem", "seize", "seldom", "select", "self",
+ "sell", "seller", "semi", "senate", "send", "senile", "senior",
+ "sense", "sensor", "sent", "sentry", "sequel", "serene", "serial",
+ "series", "sermon", "serum", "serve", "server", "set", "settle",
+ "seven", "severe", "sewage", "sex", "sexual", "sexy", "shabby",
+ "shade", "shadow", "shady", "shaft", "shaggy", "shah", "shake",
+ "shaky", "shall", "sham", "shame", "shape", "share", "shark",
+ "sharp", "shawl", "she", "shear", "sheen", "sheep", "sheer",
+ "sheet", "shelf", "shell", "sherry", "shield", "shift", "shine",
+ "shiny", "ship", "shire", "shirt", "shit", "shiver", "shock",
+ "shoe", "shook", "shoot", "shop", "shore", "short", "shot",
+ "should", "shout", "show", "shower", "shrank", "shrewd", "shrill",
+ "shrimp", "shrine", "shrink", "shrub", "shrug", "shut", "shy",
+ "shyly", "sick", "side", "siege", "sigh", "sight", "sigma", "sign",
+ "signal", "silent", "silk", "silken", "silky", "sill", "silly",
+ "silver", "simple", "simply", "since", "sinful", "sing", "singer",
+ "single", "sink", "sir", "siren", "sister", "sit", "site", "six",
+ "sixth", "sixty", "size", "sketch", "skill", "skin", "skinny",
+ "skip", "skirt", "skull", "sky", "slab", "slack", "slain", "slam",
+ "slang", "slap", "slate", "slater", "slave", "sleek", "sleep",
+ "sleepy", "sleeve", "slice", "slick", "slid", "slide", "slight",
+ "slim", "slimy", "sling", "slip", "slit", "slogan", "slope",
+ "sloppy", "slot", "slow", "slowly", "slug", "slum", "slump",
+ "smack", "small", "smart", "smash", "smear", "smell", "smelly",
+ "smelt", "smile", "smoke", "smoky", "smooth", "smug", "snack",
+ "snail", "snake", "snap", "snatch", "sneak", "snow", "snowy",
+ "snug", "soak", "soap", "sober", "soccer", "social", "sock",
+ "socket", "soda", "sodden", "sodium", "sofa", "soft", "soften",
+ "softly", "soggy", "soil", "solar", "sold", "sole", "solely",
+ "solemn", "solid", "solo", "solve", "some", "son", "sonar",
+ "sonata", "song", "sonic", "soon", "sooner", "soot", "soothe",
+ "sordid", "sore", "sorrow", "sorry", "sort", "soul", "sound",
+ "soup", "sour", "source", "space", "spade", "span", "spare",
+ "spark", "spain", "stalin", "sudan", "suez", "sunday", "sweden",
+ "swiss", "sydney", "syria", "taiwan", "sparse", "spasm", "spat",
+ "spate", "speak", "spear", "speech", "speed", "speedy", "spell",
+ "spend", "sperm", "sphere", "spice", "spicy", "spider", "spiky",
+ "spill", "spin", "spinal", "spine", "spiral", "spirit", "spit",
+ "spite", "splash", "split", "spoil", "spoke", "sponge", "spoon",
+ "sport", "spot", "spouse", "spray", "spread", "spree", "spring",
+ "sprint", "spur", "squad", "square", "squash", "squat", "squid",
+ "stab", "stable", "stack", "staff", "stage", "stain", "stair",
+ "stake", "stale", "stall", "stamp", "stance", "stand", "staple",
+ "star", "starch", "stare", "stark", "start", "starve", "state",
+ "static", "statue", "status", "stay", "stead", "steady", "steak",
+ "steal", "steam", "steel", "steep", "steer", "stem", "stench",
+ "step", "stereo", "stern", "stew", "stick", "sticky", "stiff",
+ "stifle", "stigma", "still", "sting", "stint", "stir", "stitch",
+ "stock", "stocky", "stone", "stony", "stool", "stop", "store",
+ "storm", "stormy", "story", "stout", "stove", "strain", "strait",
+ "strand", "strap", "strata", "straw", "stray", "streak", "stream",
+ "street", "stress", "strict", "stride", "strife", "strike",
+ "string", "strip", "strive", "stroke", "stroll", "strong", "stud",
+ "studio", "study", "stuff", "stuffy", "stunt", "stupid", "sturdy",
+ "style", "submit", "subtle", "subtly", "suburb", "such", "suck",
+ "sudden", "sue", "suffer", "sugar", "suit", "suite", "suitor",
+ "sullen", "sultan", "sum", "summer", "summit", "summon", "sun",
+ "sunny", "sunset", "super", "superb", "supper", "supple", "supply",
+ "sure", "surely", "surf", "surge", "survey", "suture", "swamp",
+ "swan", "swap", "swarm", "sway", "swear", "sweat", "sweaty",
+ "sweep", "sweet", "swell", "swift", "swim", "swine", "swing",
+ "swirl", "switch", "sword", "swore", "symbol", "synod", "syntax",
+ "syrup", "system", "table", "tablet", "taboo", "tacit", "tackle",
+ "tact", "tactic", "tail", "tailor", "take", "tale", "talent",
+ "talk", "tall", "tally", "tame", "tandem", "tangle", "tank", "tap",
+ "tape", "target", "tariff", "tart", "task", "taste", "tarzan",
+ "taurus", "tehran", "teresa", "texas", "thomas", "tibet", "tokyo",
+ "tom", "turk", "tasty", "tattoo", "taut", "tavern", "tax", "taxi",
+ "tea", "teach", "teak", "team", "tear", "tease", "tech", "teeth",
+ "tell", "temper", "temple", "tempo", "tempt", "ten", "tenant",
+ "tend", "tender", "tendon", "tennis", "tenor", "tense", "tensor",
+ "tent", "tenth", "tenure", "term", "terror", "test", "text",
+ "than", "thank", "that", "the", "their", "them", "theme", "then",
+ "thence", "theory", "there", "these", "thesis", "they", "thick",
+ "thief", "thigh", "thin", "thing", "think", "third", "thirst",
+ "thirty", "this", "thorn", "those", "though", "thread", "threat",
+ "three", "thrill", "thrive", "throat", "throne", "throng", "throw",
+ "thrust", "thud", "thug", "thumb", "thus", "thyme", "tick",
+ "ticket", "tidal", "tide", "tidy", "tie", "tier", "tiger", "tight",
+ "tile", "till", "tilt", "timber", "time", "timid", "tin", "tiny",
+ "tip", "tissue", "title", "toad", "toast", "today", "toilet",
+ "token", "told", "toll", "tomato", "tomb", "tonal", "tone",
+ "tongue", "tonic", "too", "took", "tool", "tooth", "top", "topaz",
+ "topic", "torch", "torque", "torso", "tort", "toss", "total",
+ "touch", "tough", "tour", "toward", "towel", "tower", "town",
+ "toxic", "toxin", "trace", "track", "tract", "trade", "tragic",
+ "trail", "train", "trait", "tram", "trance", "trap", "trauma",
+ "travel", "tray", "tread", "treat", "treaty", "treble", "tree",
+ "trek", "tremor", "trench", "trend", "trendy", "trial", "tribal",
+ "tribe", "trick", "tricky", "tried", "trifle", "trim", "trio",
+ "trip", "triple", "troop", "trophy", "trot", "trough", "trout",
+ "truce", "truck", "true", "truly", "trunk", "trust", "truth",
+ "try", "tsar", "tube", "tumble", "tuna", "tundra", "tune", "tung",
+ "tunic", "tunnel", "turban", "turf", "turn", "turtle", "tutor",
+ "tweed", "twelve", "turkey", "uganda", "venice", "venus", "vienna",
+ "viking", "virgo", "warsaw", "west", "yale", "twenty", "twice",
+ "twin", "twist", "two", "tycoon", "tying", "type", "tyrant",
+ "ugly", "ulcer", "ultra", "umpire", "unable", "uncle", "under",
+ "uneasy", "unfair", "unify", "union", "unique", "unit", "unite",
+ "unity", "unlike", "unrest", "unruly", "until", "update", "upheld",
+ "uphill", "uphold", "upon", "uproar", "upset", "upshot", "uptake",
+ "upturn", "upward", "urban", "urge", "urgent", "urging", "urine",
+ "usable", "usage", "use", "useful", "user", "usual", "uterus",
+ "utmost", "utter", "vacant", "vacuum", "vagina", "vague", "vain",
+ "valet", "valid", "valley", "value", "valve", "van", "vanish",
+ "vanity", "vary", "vase", "vast", "vat", "vault", "vector", "veil",
+ "vein", "velvet", "vendor", "veneer", "venom", "vent", "venue",
+ "verb", "verbal", "verge", "verify", "verity", "verse", "versus",
+ "very", "vessel", "vest", "veto", "via", "viable", "vicar", "vice",
+ "victim", "victor", "video", "view", "vigil", "vile", "villa",
+ "vine", "vinyl", "viola", "violet", "violin", "viral", "virgin",
+ "virtue", "virus", "visa", "vision", "visit", "visual", "vital",
+ "vivid", "vocal", "vodka", "vogue", "voice", "void", "volley",
+ "volume", "vomit", "vote", "vowel", "voyage", "vulgar", "wade",
+ "wage", "waist", "wait", "waiter", "wake", "walk", "walker",
+ "wall", "wallet", "walnut", "wander", "want", "war", "warden",
+ "warm", "warmth", "warn", "warp", "wary", "was", "wash", "wasp",
+ "waste", "watch", "water", "watery", "wave", "way", "weak",
+ "weaken", "wealth", "weapon", "wear", "weary", "wedge", "wee",
+ "weed", "week", "weekly", "weep", "weight", "weird", "well",
+ "were", "wet", "whale", "wharf", "what", "wheat", "wheel", "when",
+ "whence", "where", "which", "whiff", "whig", "while", "whim",
+ "whip", "whisky", "white", "who", "whole", "wholly", "whom",
+ "whore", "whose", "why", "wide", "widely", "widen", "wider",
+ "widow", "width", "wife", "wild", "wildly", "wilful", "will",
+ "willow", "win", "wind", "window", "windy", "wine", "wing", "wink",
+ "winner", "winter", "wipe", "wire", "wisdom", "wise", "wish",
+ "wit", "witch", "with", "within", "witty", "wizard", "woke",
+ "wolf", "wolves", "woman", "womb", "won", "wonder", "wood",
+ "wooden", "woods", "woody", "wool", "word", "work", "worker",
+ "world", "worm", "worry", "worse", "worst", "worth", "worthy",
+ "would", "wound", "wrap", "wrath", "wreath", "wreck", "wright",
+ "wrist", "writ", "write", "writer", "wrong", "xerox", "yacht",
+ "yard", "yarn", "yeah", "year", "yeast", "yellow", "yet", "yield",
+ "yogurt", "yolk", "you", "young", "your", "yemen", "york", "zaire",
+ "zurich", "aback", "abbey", "abbot", "abide", "ablaze", "able",
+ "youth", "zeal", "zebra", "zenith", "zero", "zigzag", "zinc",
+ "zombie", "zone",
];
diff --git a/tests/common.rs b/tests/common.rs
deleted file mode 100644
index ec4279d..0000000
--- a/tests/common.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-#[cfg(test)]
-mod tests {
- pub use cmn::Words;
- use cmn::*;
-
- #[test]
- fn test_new() {
- let new_constant = Constants::new();
- let constants = new_constant;
- assert!(constants.is_valid());
- assert!(constants.constants().len() >= 9);
- assert!(constants.constants().len() <= 16);
- }
-
- #[test]
- fn test_common_new() {
- let common = Common::new();
- assert!(common.constants().is_valid());
- assert!(common.constants().constants().len() >= 9);
- }
-
- #[test]
- fn test_constants() {
- let constants = Constants::new();
- assert!(constants.constants.len() >= 9);
- }
-
- #[test]
- fn test_words() {
- let common = Common::new();
- let words = common.words();
- assert_eq!(words.words_list().len(), 4096);
- }
-
- #[test]
- fn test_default() {
- let common = Common::default();
- assert_eq!(common.constants().constants().len(), 13);
- }
-}
diff --git a/tests/constants.rs b/tests/test_constants.rs
similarity index 77%
rename from tests/constants.rs
rename to tests/test_constants.rs
index eed1dc0..46c8a56 100644
--- a/tests/constants.rs
+++ b/tests/test_constants.rs
@@ -1,3 +1,6 @@
+// Copyright ยฉ 2023 Common (CMN) library. All rights reserved.
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
#[cfg(test)]
mod tests {
extern crate cmn;
@@ -18,9 +21,12 @@ mod tests {
fn test_constants() {
let new_constant = Constants::new();
let constants = new_constant.constants();
- assert_eq!(constants.len(), 13);
+ assert_eq!(constants.len(), 16);
- let names = constants.iter().map(|c| c.name).collect::>();
+ let names =
+ constants.iter().map(|c| c.name).collect::>();
+ assert!(names.contains(&"AVOGADRO"));
+ assert!(names.contains(&"BOLTZMANN"));
assert!(names.contains(&"EULER"));
assert!(names.contains(&"GAMMA"));
assert!(names.contains(&"HASH_ALGORITHM"));
@@ -32,7 +38,9 @@ mod tests {
assert!(names.contains(&"SILVER_RATIO"));
assert!(names.contains(&"SPECIAL_CHARS"));
assert!(names.contains(&"SQRT2"));
+ assert!(names.contains(&"SQRT3"));
assert!(names.contains(&"SQRT5"));
+ assert!(names.contains(&"TAU"));
}
#[test]
fn test_new() {
diff --git a/tests/test_lib.rs b/tests/test_lib.rs
new file mode 100644
index 0000000..c2d931e
--- /dev/null
+++ b/tests/test_lib.rs
@@ -0,0 +1,86 @@
+// Copyright ยฉ 2023 Common (CMN) library. All rights reserved.
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
+#[cfg(test)]
+mod tests {
+ pub use cmn::Words;
+ use cmn::*;
+
+ #[test]
+ fn test_new() {
+ let constants = Constants::new();
+ assert!(constants.is_valid());
+ assert!(constants.constants.len() >= 9);
+ assert!(constants.constants.len() <= 16);
+ }
+
+ #[test]
+ fn test_common_new() {
+ let constants = Constants::new();
+ assert!(constants.is_valid());
+ assert!(constants.constants.len() >= 9);
+ }
+
+ #[test]
+ fn test_constants() {
+ let constants = Constants::new();
+ let new_constants = constants.constants();
+
+ assert_eq!(new_constants.len(), 16);
+ assert_eq!(new_constants, constants.constants());
+ }
+
+ #[test]
+ fn test_words() {
+ let common = Common::new();
+ let words = common.words();
+ assert_eq!(words.words_list().len(), 4096);
+ }
+
+ #[test]
+ fn test_default() {
+ let common = Common::default();
+ let constants = common.constants();
+
+ assert_eq!(constants.constants().len(), 16);
+ assert_eq!(constants.constants(), Constants::default().constants());
+ }
+
+ #[test]
+ fn test_constants_method() {
+ let constants = Constants::new();
+ let new_constants = constants.constants();
+
+ assert_eq!(new_constants.len(), 16);
+ assert_eq!(new_constants, Constants::default().constants());
+ }
+
+ #[test]
+ fn test_constants_method_returns_copy_of_constants() {
+ let constants = Constants::new();
+ let new_constants = constants.constants().to_vec();
+
+ assert_eq!(new_constants.len(), 16);
+ assert_eq!(constants.constants().len(), 16);
+ assert_eq!(new_constants, constants.constants().to_vec());
+ }
+
+ #[test]
+ fn test_constants_method_returns_constants_instance() {
+ let constants = Constants::new();
+ let new_constants = constants.constants();
+
+ assert_eq!(new_constants.len(), 16);
+ assert_eq!(new_constants, Constants::default().constants());
+ }
+
+ #[test]
+ fn test_constants_method_returns_default_constants_instance() {
+ let constants = Constants::new();
+ let binding = Constants::default();
+ let default_constants = binding.constants();
+
+ assert_eq!(default_constants.len(), 16);
+ assert_eq!(default_constants, constants.constants());
+ }
+}
diff --git a/tests/test_macros.rs b/tests/test_macros.rs
new file mode 100644
index 0000000..4fc0dde
--- /dev/null
+++ b/tests/test_macros.rs
@@ -0,0 +1,158 @@
+#[cfg(test)]
+mod tests {
+
+ // Importing cmn crate and all of its macros
+ extern crate cmn;
+ use cmn::{
+ cmn_assert, cmn_contains, cmn_in_range, cmn_join, cmn_max,
+ cmn_min, cmn_print, cmn_print_vec, cmn_split, cmn_vec,
+ constants::*,
+ };
+
+ #[test]
+ #[should_panic(expected = "Assertion failed!")]
+ fn test_cmn_assert_fail() {
+ // Test that cmn_assert! macro correctly triggers a panic when the argument is false
+ cmn_assert!(false);
+ }
+
+ #[test]
+ fn test_cmn_assert() {
+ // Test that cmn_assert! macro does not trigger a panic when the argument is true
+ cmn_assert!(true);
+ }
+
+ #[test]
+ fn test_cmn_join() {
+ // Test that cmn_join! macro correctly joins the string arguments together
+ let s = cmn_join!("Hello", " ", "World");
+ assert_eq!(s, "Hello World");
+ }
+
+ #[test]
+ fn test_cmn_min() {
+ // Test that cmn_min! macro correctly identifies the minimum value among the arguments
+ assert_eq!(cmn_min!(10, 20, 30), 10);
+ }
+
+ #[test]
+ fn test_cmn_max() {
+ // Test that cmn_max! macro correctly identifies the maximum value among the arguments
+ assert_eq!(cmn_max!(10, 20, 30), 30);
+ }
+
+ #[test]
+ fn test_cmn_print() {
+ // Test that cmn_print! macro correctly prints the argument
+ cmn_print!("Hello, World!");
+ }
+
+ #[test]
+ fn test_cmn_print_vec() {
+ // Test that cmn_print_vec! macro correctly prints the elements of the vector argument
+ cmn_print_vec!(&[1, 2, 3]);
+ }
+
+ #[test]
+ fn test_cmn_split() {
+ // Test that cmn_split! macro correctly splits the string argument into a vector of words
+ let v = cmn_split!("Hello World");
+ assert_eq!(v, vec!["Hello", "World"]);
+ }
+
+ #[test]
+ fn test_cmn_vec() {
+ // Test that cmn_vec! macro correctly creates a vector from the arguments
+ let v = cmn_vec!(1, 2, 3);
+ assert_eq!(v, &[1, 2, 3]);
+ }
+
+ #[test]
+ fn test_cmn_contains() {
+ // Test that cmn_contains! macro correctly checks if the first string contains the second
+ assert!(cmn_contains!("Hello", "H"));
+ assert!(!cmn_contains!("Hello", "x"));
+ }
+
+ #[test]
+ fn test_cmn_in_range() {
+ // Test that cmn_in_range! macro correctly checks if a number is within a range
+ assert!(cmn_in_range!(10, 0, 100));
+ assert!(!cmn_in_range!(-10, 0, 100));
+ }
+
+ #[test]
+ fn test_cmn_constants() {
+ // Test that each constant defined by the cmn_constants! macro has the expected value or is not empty
+ assert_eq!(
+ AVOGADRO, 6.02214076e23,
+ "AVOGADRO should have a specific value"
+ );
+ assert_eq!(
+ BOLTZMANN, 1.380648e-23,
+ "BOLTZMANN should have a specific value"
+ );
+ assert_eq!(
+ EULER, std::f64::consts::E,
+ "EULER should have a specific value"
+ );
+ assert_eq!(
+ GAMMA, 0.5772156649015329,
+ "GAMMA should have a specific value"
+ );
+ assert_eq!(
+ HASH_ALGORITHM, "Blake3",
+ "HASH_ALGORITHM should have a specific value"
+ );
+ assert_eq!(
+ HASH_COST, 8,
+ "HASH_COST should have a specific value"
+ );
+ assert_eq!(
+ HASH_LENGTH, 32,
+ "HASH_LENGTH should have a specific value"
+ );
+ assert_eq!(
+ PHI,
+ (1.0 + SQRT5) / 2.0,
+ "PHI should have a specific value"
+ );
+ assert_eq!(
+ PI,
+ std::f64::consts::PI,
+ "PI should have a specific value"
+ );
+ assert_eq!(
+ PLANCK, 6.62607015e-34,
+ "PLANCK should have a specific value"
+ );
+ assert_eq!(
+ SILVER_RATIO,
+ 1.0 + SQRT2,
+ "SILVER_RATIO should have a specific value"
+ );
+ assert_eq!(
+ SPECIAL_CHARS,
+ &[
+ '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_',
+ '+', '=', '[', ']', '{', '}', '|', ';', ':', '"', '<',
+ '>', ',', '.', '?', '/', '~', '`'
+ ],
+ "SPECIAL_CHARS should have a specific value"
+ );
+ assert_eq!(
+ SQRT2,
+ std::f64::consts::SQRT_2,
+ "SQRT2 should have a specific value"
+ );
+ assert_eq!(
+ SQRT3, 1.7320508075688772,
+ "SQRT3 should have a specific value"
+ );
+ assert_eq!(
+ SQRT5, 2.23606797749979,
+ "SQRT5 should have a specific value"
+ );
+ assert_eq!(TAU, 2.0 * PI, "TAU should have a specific value");
+ }
+}
diff --git a/tests/test_main.rs b/tests/test_main.rs
new file mode 100644
index 0000000..b18cbe1
--- /dev/null
+++ b/tests/test_main.rs
@@ -0,0 +1,64 @@
+#[cfg(test)]
+mod tests {
+ use assert_cmd::prelude::*;
+ use std::process::Command;
+
+ #[test]
+ fn test_run_with_cmn_test_mode() {
+ let output = Command::cargo_bin("cmn")
+ .unwrap()
+ .env("CMN_TEST_MODE", "1")
+ .output()
+ .expect("Failed to execute command");
+
+ // Assert that the command execution was not successful
+ assert!(!output.status.success());
+
+ // Assert that the error message was printed to stderr
+ let stderr = String::from_utf8(output.stderr).unwrap();
+ assert!(stderr.contains("Error running cmn: Simulated error"));
+ }
+
+ #[test]
+ fn test_run_without_cmn_test_mode() {
+ let output = Command::cargo_bin("cmn")
+ .unwrap()
+ .output()
+ .expect("Failed to execute command");
+
+ // Assert that the command execution was successful
+ assert!(output.status.success());
+
+ // Assert that the welcome messages were printed to stdout
+ let stdout = String::from_utf8(output.stdout).unwrap();
+ assert!(stdout.contains("Welcome to `CMN` ๐!"));
+ assert!(stdout.contains("A Rust library for accessing a collection of mathematical and cryptographic constants."));
+ }
+
+ fn run_test_scenario() -> Result<(), Box> {
+ // Simulate an error scenario
+ // Return an error explicitly
+ Err("Test error".into())
+ }
+
+ #[test]
+ fn test_main() {
+ // Test calling the `run()` function directly
+ let result = run_test_scenario();
+ assert!(result.is_err());
+
+ // Test calling the `main()` function
+ let output = Command::cargo_bin("cmn")
+ .unwrap()
+ .env("CMN_TEST_MODE", "1")
+ .output()
+ .expect("Failed to execute command");
+
+ // Assert that the command execution was not successful
+ assert!(!output.status.success());
+
+ // Assert that the error message was printed to stderr
+ let stderr = String::from_utf8(output.stderr).unwrap();
+ assert!(stderr.contains("Error running cmn: Simulated error"));
+ }
+}
diff --git a/tests/words.rs b/tests/test_words.rs
similarity index 83%
rename from tests/words.rs
rename to tests/test_words.rs
index 3edcf39..7d47203 100644
--- a/tests/words.rs
+++ b/tests/test_words.rs
@@ -1,3 +1,6 @@
+// Copyright ยฉ 2023 Common (CMN) library. All rights reserved.
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
#[cfg(test)]
mod tests {
pub use cmn::Words;
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
new file mode 100644
index 0000000..1f83fab
--- /dev/null
+++ b/xtask/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "xtask"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+anyhow = "1.0.71"
+xtaskops = "0.4.2"
+
+[[bin]]
+name = "xtask"
+path = "src/main.rs"
diff --git a/xtask/src/main.rs b/xtask/src/main.rs
new file mode 100644
index 0000000..c58cdf1
--- /dev/null
+++ b/xtask/src/main.rs
@@ -0,0 +1,13 @@
+//! This is the main entry point for the xtask crate.
+//!
+//! The `main()` function serves as the starting point of the executable.
+//! It returns a `Result<(), anyhow::Error>`, indicating success or failure.
+//! The `xtaskops::tasks::main()` function is called to perform the main tasks.
+//!
+//! # Errors
+//!
+//! If an error occurs during the execution of the tasks, an `anyhow::Error` is returned.
+
+fn main() -> Result<(), anyhow::Error> {
+ xtaskops::tasks::main()
+}