# Contributing to uninum
`uninum` is developed and maintained exclusively by **Synext Solution Sdn. Bhd.**
While the project is open source, we do not accept external pull requests.
Community members are encouraged to open issues for bugs, security reports, or
feature ideas, but roadmap and code changes remain at the sole discretion of
Synext Solution. Feel free to fork the repository under the dual MIT/Apache-2.0
license if you need custom behaviour.
This document explains how to provide feedback and, for internal maintainers,
records the workflow we follow when updating the project.
## How Can I Provide Feedback?
Even though we do not merge outside code changes, issue reports are very much
appreciated:
* **Reporting Bugs**: If you find unexpected behaviour, please open an issue on
our [GitHub Issues](https://github.com/Synext-Solution/uninum/issues) page with
steps to reproduce the problem.
* **Suggesting Enhancements**: Have an idea for a new feature or API tweak?
Start a discussion in an issue so we can evaluate it for the roadmap.
* **Improving Documentation**: Documentation fixes are welcome via issues. You
can also maintain your own fork if you need immediate changes.
Pull requests opened by external contributors will be closed with a pointer to
the relevant issue so that all discussion stays in one place.
### Reporting Bugs
Before submitting a bug report, please search the existing issues to see if a similar one has already been reported. When creating a new bug report, please include:
1. A clear and descriptive title (e.g., "Panic on division of `i64::MIN` by `-1`").
2. The version of `uninum` you are using.
3. A minimal, reproducible code example that demonstrates the bug.
4. What you expected to happen.
5. What actually happened, including any error messages or panic backtraces.
### Suggesting Enhancements
We welcome new ideas! If you have a suggestion for a new feature or an API improvement, please open an issue to propose it. This allows us to discuss the design, trade-offs, and alignment with the project's goals before you invest significant time in implementation.
## Internal Maintainer Workflow (Synext Solution Sdn. Bhd.)
The remaining sections document how Synext engineers make changes to the
repository. External contributors do not need to follow these steps.
#### 1. Fork & Clone the Repository
First, fork the repository to your own GitHub account, and then clone it to your local machine:
```bash
git clone https://github.com/Synext-Solution/uninum.git
cd uninum
```
#### 2. Set Up Your Development Environment
`uninum` is a standard Rust project. All you need is the Rust toolchain installed via [rustup](https://rustup.rs/).
#### 3. Create a Branch
Create a new branch for your changes from the `main` branch. Please use a descriptive name that follows a conventional format.
```bash
# For a new feature
git checkout -b feat/add-abs-function
# For a bug fix
git checkout -b fix/pow-negative-base-edge-case
```
#### 4. Write and Verify Your Code
Make your changes to the code, following the existing style and structure to maintain consistency.
> **Minimum supported Rust version:** The project targets Rust 1.88.0. Run local
> checks with that toolchain (`rustup toolchain install 1.88.0` and
> `cargo +1.88.0 …`) if you introduce new dependencies or language features.
#### Our Dependency Policy
`uninum` intentionally keeps its core zero-dependency when optional features are
disabled. Any new dependency must be approved internally before landing. If a
dependency is accepted, it should be gated behind a feature flag and documented
in the README feature table.
#### Local Automation (recommended)
To make it easy to follow the quality gates we provide:
* A [pre-commit](https://pre-commit.com/) configuration. After installing the
tool, run:
```bash
pre-commit install
pre-commit install --hook-type commit-msg
pre-commit run --all-files
```
The hook runs `cargo fmt`, `cargo clippy --all-features`, and the full test
suite before each commit, and enforces Conventional Commit formatting on
commit messages. Regenerate the changelog during release preparation.
* A pre-push helper script: `scripts/pre-push.sh`. You can wire it up with:
```bash
ln -sf ../../scripts/pre-push.sh .git/hooks/pre-push
```
The script enforces formatting, linting, and testing for both the default and
minimal feature sets before a push.
##### Quality Gates: Our Standards for Code
To ensure `uninum` remains a high-quality and reliable library, we enforce a strict set of quality gates. **All checks must pass before a pull request can be merged.**
1. **Test**: Run the entire test suite, including tests for all feature combinations. If you add new functionality, you must add corresponding tests to ensure its correctness and prevent future regressions.
```bash
cargo test --all-features
```
2. **Format**: Ensure your code is formatted according to the standard Rust style.
```bash
cargo fmt --all
```
3. **Lint (Clippy)**: We enforce a strict Clippy standard, including the `pedantic` and `nursery` lints, to maintain the highest code quality. Your contribution must pass Clippy with **zero warnings**.
```bash
cargo clippy --all-features -- -D warnings
```
**Justifying `#[allow]` Attributes**: We recognize that there are rare, legitimate cases where a specific Clippy lint must be disabled. If you need to use `#[allow(clippy::...)]`, you **must** provide a clear, concise comment on the line directly above the attribute explaining *why* it is necessary for that specific instance.
For example, this project allows `clippy::multiple_crate_versions` with the following justification:
```rust
#![cfg_attr(clippy, allow(clippy::multiple_crate_versions))]
```
Pull requests that disable lints without a clear and valid justification will not be accepted.
#### 5. Add Documentation
If you are adding a new public function or feature, you must add comprehensive `///` doc comments with examples, just like the existing code. If you are changing existing functionality, update the documentation accordingly.
#### 6. Commit Your Changes
We follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification. This helps us automate changelog generation and makes the Git history easy to read.
Our tooling will reject commits that do not match the required pattern. See the
examples below or run `scripts/verify-commit-msg.sh <message>` manually to check
your message before committing.
Before cutting a release, regenerate the changelog to capture the latest
Conventional Commits:
```bash
cargo install git-cliff --locked # first-time setup
scripts/update-changelog.sh
```
CI will fail if `CHANGELOG.md` does not match the output of the script.
Common prefixes include:
* `feat:` (a new feature)
* `fix:` (a bug fix)
* `docs:` (documentation-only changes)
* `test:` (adding or improving tests)
* `refactor:` (code changes that neither fix a bug nor add a feature)
* `chore:` (build process, tooling, etc.)
Example:
```bash
git commit -m "feat: Add `abs()` method for Number" -m "Adds a new method to calculate the absolute value, promoting unsigned types to signed types if necessary."
```
#### 7. Submit a Pull Request
Push your branch to your fork and open a pull request against the `main` branch of the `uninum` repository. In your pull request description, please:
* Briefly describe the changes you have made.
* Link to the issue you are addressing (e.g., "Fixes #123").
## Pull Request Process
1. Once you submit your PR, our automated CI pipeline will run all the checks (test, format, lint). The CI must pass before the PR can be reviewed.
2. A maintainer will review your code and may suggest some changes or improvements.
3. Once the review is complete and all checks are passing, a maintainer will merge your contribution.
## Licensing
By contributing to `uninum`, you agree that your contributions will be licensed under both the MIT License and the Apache License 2.0, as defined in the `LICENSE-MIT` and `LICENSE-APACHE` files.