aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author简律纯 <i@jyunko.cn>2024-02-26 15:34:36 +0800
committerGitHub <noreply@github.com>2024-02-26 15:34:36 +0800
commit4426854b2788804bc4dfe3826a63959f973df416 (patch)
tree7c5da56819c7249966b9d3d6b027eb7a5c8ec652
parentf5b87bb917a1cbad5ba81d3860b358129831bcae (diff)
downloadHydroRoll-4426854b2788804bc4dfe3826a63959f973df416.tar.gz
HydroRoll-4426854b2788804bc4dfe3826a63959f973df416.zip
refactor(core): rewrite HydroRoll in rust (#91)
* refactor(command): 重构命令路由 * feat(lua): 包装异步方法`self.event.reply` => `msg:echo` * feat(lua): 包装异步输入流方法`self.event.ask` => `msg:ask` * 'Refactored by Sourcery' (#83) Co-authored-by: Sourcery AI <> * feat(Token|Lexer): 添加`Token`与`Lexer`类 * refactor(Lexer): 词法分析器添加`advance`方法 * chore: lint code * refactor: sync gensokyo adapter * feat: Cli parser (#85) * feat(cli): 添加`Cli`类,解析命令行参数 * fix: 修复错误的`dest`与`action` * feat(cli): 实现`install_package` 与 `build_template` * feat(cli): 实现`-c|--config`指令配置镜像常量等 * feat(cli): 使用高效率的异步网络库`aiohttp` * fix(cli): `TYPE_CHECKING` with partially module `typing` * refactor!: examples, tests, src... rewrite in rust * chore(workflow): add changelog ci workflow * fix(workflow): sync upload target branch * chore(readme): update profile * chore(readme): update profile x2 * chore(readme): fix wrong pronounce * chore(readme): add top tile * chore(readme): remove invalid uri * chore(readme): update profile for new development * chore(readme): rewrite with rst * refactor!: rewrite HydrRoll in Rust --------- Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
-rw-r--r--.github/workflows/changelog.yml47
-rw-r--r--.github/workflows/release.yml146
-rw-r--r--.template/Cargo.toml13
-rw-r--r--.template/pre-script.rhai4
-rw-r--r--.template/pyproject.toml13
-rw-r--r--Cargo.lock273
-rw-r--r--Cargo.toml12
-rw-r--r--MANIFEST.in2
-rw-r--r--README.rst146
-rw-r--r--cargo-generate.toml5
-rw-r--r--noxfile.py17
-rw-r--r--src/lib.rs14
12 files changed, 663 insertions, 29 deletions
diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml
new file mode 100644
index 0000000..e89687a
--- /dev/null
+++ b/.github/workflows/changelog.yml
@@ -0,0 +1,47 @@
+name: CHANGELOG
+
+on:
+ push:
+ tags:
+ - "v*"
+ # - v[0-9]+.[0-9]+.[0-9]+
+ workflow_dispatch:
+
+jobs:
+ deploy:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ pull-requests: write
+ id-token: write
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v4
+
+ - name: Update CHANGELOG
+ id: changelog
+ uses: requarks/changelog-action@v1
+ with:
+ token: ${{ github.token }}
+ tag: ${{ github.ref_name }}
+ includeInvalidCommits: true
+ changelogFilePath: CHANGELOG.md
+ writeToFile: true
+ useGitmojis: false
+
+ - name: Create Release
+ uses: ncipollo/release-action@v1.14.0
+ with:
+ allowUpdates: true
+ draft: false
+ makeLatest: true
+ name: ${{ github.ref_name }}
+ body: ${{ steps.changelog.outputs.changes }}
+ token: ${{ github.token }}
+
+ - name: Commit CHANGELOG.md
+ uses: stefanzweifel/git-auto-commit-action@v5
+ with:
+ branch: main
+ commit_message: 'docs: update CHANGELOG.md for ${{ github.ref_name }} [skip ci]'
+ file_pattern: CHANGELOG.md
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 54eeb31..4ebdf64 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -1,29 +1,117 @@
-name: Release
-
-on:
- push:
- tags:
- - "v*"
- workflow_dispatch:
-
-jobs:
- build:
- runs-on: ubuntu-latest
- env:
- PDM_PUBLISH_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
- PDM_PUBLISH_USERNAME: ${{ secrets.PYPI_USERNAME }}
- steps:
- - uses: actions/checkout@v3
-
- - name: Install pdm
- run: pipx install pdm
- shell: bash
- - uses: actions/setup-python@v4
- with:
- python-version: "3.9"
- architecture: "x64"
- - run: pdm install
- shell: bash
-
- - run: pdm publish
- shell: bash \ No newline at end of file
+# This file is autogenerated by maturin v1.4.0
+# To update, run
+#
+# maturin generate-ci github
+#
+name: Release
+
+on:
+ push:
+ branches:
+ - main
+ tags:
+ - 'v*'
+ pull_request:
+ workflow_dispatch:
+
+permissions:
+ contents: read
+
+jobs:
+ linux:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ target: [x86_64, x86, aarch64, armv7, s390x, ppc64le]
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v4
+ with:
+ python-version: '3.10'
+ - name: Build wheels
+ uses: PyO3/maturin-action@v1
+ with:
+ target: ${{ matrix.target }}
+ args: --release --out dist --find-interpreter
+ sccache: 'true'
+ manylinux: auto
+ - name: Upload wheels
+ uses: actions/upload-artifact@v3
+ with:
+ name: wheels
+ path: dist
+
+ windows:
+ runs-on: windows-latest
+ strategy:
+ matrix:
+ target: [x64, x86]
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v4
+ with:
+ python-version: '3.10'
+ architecture: ${{ matrix.target }}
+ - name: Build wheels
+ uses: PyO3/maturin-action@v1
+ with:
+ target: ${{ matrix.target }}
+ args: --release --out dist --find-interpreter
+ sccache: 'true'
+ - name: Upload wheels
+ uses: actions/upload-artifact@v3
+ with:
+ name: wheels
+ path: dist
+
+ macos:
+ runs-on: macos-latest
+ strategy:
+ matrix:
+ target: [x86_64, aarch64]
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v4
+ with:
+ python-version: '3.10'
+ - name: Build wheels
+ uses: PyO3/maturin-action@v1
+ with:
+ target: ${{ matrix.target }}
+ args: --release --out dist --find-interpreter
+ sccache: 'true'
+ - name: Upload wheels
+ uses: actions/upload-artifact@v3
+ with:
+ name: wheels
+ path: dist
+
+ sdist:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: Build sdist
+ uses: PyO3/maturin-action@v1
+ with:
+ command: sdist
+ args: --out dist
+ - name: Upload sdist
+ uses: actions/upload-artifact@v3
+ with:
+ name: wheels
+ path: dist
+
+ release:
+ name: Release
+ runs-on: ubuntu-latest
+ if: "startsWith(github.ref, 'refs/tags/')"
+ needs: [linux, windows, macos, sdist]
+ steps:
+ - uses: actions/download-artifact@v3
+ with:
+ name: wheels
+ - name: Publish to PyPI
+ uses: PyO3/maturin-action@v1
+ with:
+ command: upload
+ args: --non-interactive --skip-existing *
diff --git a/.template/Cargo.toml b/.template/Cargo.toml
new file mode 100644
index 0000000..1997d0d
--- /dev/null
+++ b/.template/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+authors = ["{{authors}}"]
+name = "{{project-name}}"
+version = "0.1.0"
+edition = "2021"
+
+[lib]
+name = "hydrorolldemo"
+crate-type = ["cdylib"]
+
+[dependencies]
+pyo3 = { version = "{{PYO3_VERSION}}", features = ["extension-module"] }
+rayon = "1.0.2"
diff --git a/.template/pre-script.rhai b/.template/pre-script.rhai
new file mode 100644
index 0000000..f059903
--- /dev/null
+++ b/.template/pre-script.rhai
@@ -0,0 +1,4 @@
+variable::set("PYO3_VERSION", "0.20.3");
+file::rename(".template/Cargo.toml", "Cargo.toml");
+file::rename(".template/pyproject.toml", "pyproject.toml");
+file::delete(".template");
diff --git a/.template/pyproject.toml b/.template/pyproject.toml
new file mode 100644
index 0000000..8aa3c95
--- /dev/null
+++ b/.template/pyproject.toml
@@ -0,0 +1,13 @@
+[build-system]
+requires = ["maturin>=1,<2"]
+build-backend = "maturin"
+
+[project]
+name = "{{project-name}}"
+version = "0.1.0"
+
+[project.optional-dependencies]
+dev = ["pytest"]
+
+[tool.pytest.ini_options]
+addopts = "--benchmark-disable"
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..623d9e7
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,273 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "HydroRoll"
+version = "0.1.0"
+dependencies = [
+ "pyo3",
+]
+
+[[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 = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "indoc"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306"
+
+[[package]]
+name = "libc"
+version = "0.2.153"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
+
+[[package]]
+name = "lock_api"
+version = "0.4.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
+name = "memoffset"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
+
+[[package]]
+name = "parking_lot"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-targets",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "pyo3"
+version = "0.19.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e681a6cfdc4adcc93b4d3cf993749a4552018ee0a9b65fc0ccfad74352c72a38"
+dependencies = [
+ "cfg-if",
+ "indoc",
+ "libc",
+ "memoffset",
+ "parking_lot",
+ "pyo3-build-config",
+ "pyo3-ffi",
+ "pyo3-macros",
+ "unindent",
+]
+
+[[package]]
+name = "pyo3-build-config"
+version = "0.19.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "076c73d0bc438f7a4ef6fdd0c3bb4732149136abd952b110ac93e4edb13a6ba5"
+dependencies = [
+ "once_cell",
+ "target-lexicon",
+]
+
+[[package]]
+name = "pyo3-ffi"
+version = "0.19.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e53cee42e77ebe256066ba8aa77eff722b3bb91f3419177cf4cd0f304d3284d9"
+dependencies = [
+ "libc",
+ "pyo3-build-config",
+]
+
+[[package]]
+name = "pyo3-macros"
+version = "0.19.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfeb4c99597e136528c6dd7d5e3de5434d1ceaf487436a3f03b2d56b6fc9efd1"
+dependencies = [
+ "proc-macro2",
+ "pyo3-macros-backend",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "pyo3-macros-backend"
+version = "0.19.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "947dc12175c254889edc0c02e399476c2f652b4b9ebd123aa655c224de259536"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+
+[[package]]
+name = "smallvec"
+version = "1.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
+
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "target-lexicon"
+version = "0.12.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+
+[[package]]
+name = "unindent"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1766d682d402817b5ac4490b3c3002d91dfa0d22812f341609f97b08757359c"
+
+[[package]]
+name = "windows-targets"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..7d6cfc9
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "HydroRoll"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+[lib]
+name = "__force"
+crate-type = ["cdylib"]
+
+[dependencies]
+pyo3 = "0.19.0"
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..becccf7
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,2 @@
+include pyproject.toml Cargo.toml
+recursive-include src *
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..588d272
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,146 @@
+.. raw:: html
+ <div align="right">|logo_icon|</div>
+
+.. raw:: html
+ <div align="right">|logo_icon|</div>
+
+HydroRoll'水系
+============
+
+|ruff| |python_v| |community| |docs|
+|ruff| |python_v| |community| |docs|
+
+.. _getting:
+
+快速开始
+----
+
+ 仅需三步即可快速搭建一个符合水系标准的骰子机器人。你也可以在我们的 `官方文档`_ 查看更详细的部署与配置教程。
+快速开始
+----
+
+ 仅需三步即可快速搭建一个符合水系标准的骰子机器人。你也可以在我们的 `官方文档`_ 查看更详细的部署与配置教程。
+
+1. 安装库
+
+推荐局部安装,使用 *pdm* 创建一个虚拟环境后在命令行输入,
+推荐局部安装,使用 *pdm* 创建一个虚拟环境后在命令行输入,
+
+.. code:: shell
+
+ pdm add hydroroll[all]
+
+这会在当前虚拟环境添加 *extra* 版本的 *HydroRoll*,包括 `自动热重载`_ (*hot-reload*)、`调度任务`_ (*apscheduler*) 与 `基础模型`_ (*base-model*) 等。
+
+这会在当前虚拟环境添加 *extra* 版本的 *HydroRoll*,包括 `自动热重载`_ (*hot-reload*)、`调度任务`_ (*apscheduler*) 与 `基础模型`_ (*base-model*) 等。
+
+2. 创建机器人实例
+
+在终端中输入执行以下指令,
+
+在终端中输入执行以下指令,
+
+.. code:: shell
+
+ hydroroll new -b coc_example "HydroRoll"
+
+这会在当前 *pwd* 环境的根目录下使用内置的 *coc_example* `规则包`_ 创建一个名为 "HydroRoll" 的骰子文件夹,您的所有骰子相关内容均在此文件夹中。
+ hydroroll new -b coc_example "HydroRoll"
+
+这会在当前 *pwd* 环境的根目录下使用内置的 *coc_example* `规则包`_ 创建一个名为 "HydroRoll" 的骰子文件夹,您的所有骰子相关内容均在此文件夹中。
+
+.. code:: shell
+
+ tree HydroRoll
+
+ HydroRoll
+ ├─models
+ ├─config
+ ├─data
+ ├─rules
+ ├─scripts
+ └─web
+ ├─backend
+ └─frontend
+
+3. 使用合适的适配器, 合理修改你的 *config.toml* 配置文件, 等待连接!
+.. code:: shell
+
+ tree HydroRoll
+
+ HydroRoll
+ ├─models
+ ├─config
+ ├─data
+ ├─rules
+ ├─scripts
+ └─web
+ ├─backend
+ └─frontend
+
+3. 使用合适的适配器, 合理修改你的 *config.toml* 配置文件, 等待连接!
+
+.. code:: python
+
+ hydroroll run
+ # 使用 pdm run main.py 同理
+ hydroroll run
+ # 使用 pdm run main.py 同理
+
+.. _contributing:
+
+Contributing
+---------------
+
+欢迎阅读 `CONTRIBUTING.md <./CONTRIBUTING.md>`__ 对水系的各个模块与标准做出贡献。
+欢迎阅读 `CONTRIBUTING.md <./CONTRIBUTING.md>`__ 对水系的各个模块与标准做出贡献。
+
+.. _community:
+
+Community
+----------
+
+HydroRoll'水系 的论坛在 `GitHub
+Discussions <https://github.com/orgs/HydroRoll-Team/discussions>`__,
+你可以在这里 `提出任何问题 <https://github.com/HydroRoll-Team/HydroRoll/issues/new>`__, `分享任何想法 <https://github.com/HydroRoll-Team/HydroRoll/pulls>`__。
+你可以在这里 `提出任何问题 <https://github.com/HydroRoll-Team/HydroRoll/issues/new>`__, `分享任何想法 <https://github.com/HydroRoll-Team/HydroRoll/pulls>`__。
+
+我们的 `行为准则(Code of Conduct) <./CODE_OF_CONDUCT.md>`__ 适用于
+HydroRoll'水系 社区内的所有交流渠道。
+
+.. _license:
+
+License
+----------
+
+`MIT`_ © 2023-PRESENT `简律纯`_ & `HydroRoll-Team`_.
+
+.. uri list above:
+.. _自动热重载: https://docs.hydroroll.team/addons/hot-reload
+.. _调度任务: https://docs.hydroroll.team/addons/apscheduler
+.. _基础模型: https://docs.hydroroll.team/addons/base-model
+.. _规则包: https://docs.hydroroll.team/advanced/rule-package
+.. _官方文档: https://docs.hydroroll.team/
+.. _MIT: https://github.com/HydroRoll-Team/HydroRoll/blob/main/LICENSE
+.. _简律纯: https://github.com/HsiangNianian
+.. _HydroRoll-Team: https://github.com/HydroRoll-Team
+
+.. image list above:
+.. |Structure| image:: https://images.repography.com/39938419/HydroRoll-Team/HydroRoll/structure/ZbjPFFiNYq0UR3cTqEwQHLzqWSn3SeO30n9Nk3SwmVU/-8GQ3jezs4jjRVX5ZbACiuiSwmPbkzEdEQAyP2ednF0_table.svg
+ :target: https://github.com/HydroRoll-Team/HydroRoll
+ :alt: Structure
+.. |ruff| image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
+ :target: https://github.com/astral-sh/ruff
+ :alt: Ruff
+.. |logo_icon| image:: https://cdn.jsdelivr.net/gh/HydroRoll-Team/HydroRoll@main/site/src/assets/image/logo.png
+ :target: https://hydroroll.team/
+ :alt: HydroRoll Logo
+ :height: 128
+.. |docs| image:: https://img.shields.io/badge/DOCS%20AND%20BLOGS-000000.svg?logo=Vercel&labelColor=000&style=flat-square
+ :target: https://docs.hydroroll.team/
+ :alt: Documentation
+.. |python_v| image:: https://img.shields.io/pypi/v/hydroroll.svg?labelColor=000000&style=flat-square
+ :target: https://pypi.org/project/hydroroll/
+.. |community| image:: https://img.shields.io/badge/Join%20the%20community-002fa7.svg?logo=data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8CAgL/CgoK/woKCv8GBgb/BgYG/woKCv8KCgr/AgIC/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/BgYG/0ZGRv9MTEz/JiYm/ygoKP9MTEz/RkZG/wYGBv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP9ycnL/Li4u/1xcXP9eXl7/Li4u/3Jycv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP88PDz/cnJy/05OTv9OTk7/UFBQ/05OTv9wcHD/Pj4+/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/Kioq/3Jycv9cXFz/TExM/05OTv9aWlr/cHBw/yoqKv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/Pj4+/zg4OP+AgID/Pj4+/2ZmZv9oaGj/PDw8/4CAgP86Ojr/Pj4+/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/ywsLP9iYmL/enp6/zIyMv90dHT/dHR0/zAwMP98fHz/YmJi/ywsLP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP9SUlL/PDw8/3Jycv9CQkL/UlJS/1RUVP9CQkL/cnJy/zw8PP9SUlL/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/VFRU/yIiIv9aWlr/PDw8/zw8PP8+Pj7/PDw8/1hYWP8iIiL/VFRU/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/zQ0NP9CQkL/ZmZm/yIiIv9WVlb/WFhY/yIiIv9mZmb/QkJC/zY2Nv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP9QUFD/BgYG/0RERP9KSkr/JCQk/yYmJv9KSkr/RERE/wgICP9QUFD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/CgoK/wICAv8KCgr/CgoK/wYGBv8GBgb/CgoK/woKCv8CAgL/CgoK/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==&labelColor=000000&logoWidth=20&logoColor=white&style=flat-square
+ :target: https://github.com/orgs/HydroRoll-Team/discussions
+ :alt: Join The Community
diff --git a/cargo-generate.toml b/cargo-generate.toml
new file mode 100644
index 0000000..d750c4d
--- /dev/null
+++ b/cargo-generate.toml
@@ -0,0 +1,5 @@
+[template]
+ignore = [".nox"]
+
+[hooks]
+pre = [".template/pre-script.rhai"]
diff --git a/noxfile.py b/noxfile.py
new file mode 100644
index 0000000..d64f210
--- /dev/null
+++ b/noxfile.py
@@ -0,0 +1,17 @@
+import nox
+
+nox.options.sessions = ["test"]
+
+
+@nox.session
+def test(session: nox.Session):
+ session.env["MATURIN_PEP517_ARGS"] = "--profile=dev"
+ session.install(".[dev]")
+ session.run("pytest")
+
+
+@nox.session
+def bench(session: nox.Session):
+ session.env["MATURIN_PEP517_ARGS"] = "--profile=dev"
+ session.install(".[dev]")
+ session.run("pytest", "--benchmark-enable")
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..c2edaae
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,14 @@
+use pyo3::prelude::*;
+
+/// Formats the sum of two numbers as string.
+#[pyfunction]
+fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
+ Ok((a + b).to_string())
+}
+
+/// A Python module implemented in Rust.
+#[pymodule]
+fn __force(_py: Python, m: &PyModule) -> PyResult<()> {
+ m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;
+ Ok(())
+}