build(ariadne): vendor serde crates
This commit was merged in pull request #15.
This commit is contained in:
1 parent
90f46026f0
commit
64773e0948
490 files changed
+175103
No files matched your search
@@ -0,0 +1 @@
|
||||
{"$comment":"This file only protects against accidental modifications. It is not a security mechanism and does not protect against malicious changes.","files":{".cargo_vcs_info.json":"e0165305f3b22a9ab4217a121f85379aa56c2675caa7afedc0a7468fc187600b",".github/FUNDING.yml":"b017158736b3c9751a2d21edfce7fe61c8954e2fced8da8dd3013c2f3e295bd9",".github/workflows/ci.yml":"89c4f60223daf03217ea7c1e8879135b11d2554bd1e57dd9eff5c02f1adc7909","Cargo.lock":"1cd64090b8e883963bb08d91e6968cc1e83ffdba4f4b2f47651ce9d351a8a947","Cargo.toml":"894c215e4e7e973b556b0e9627bf9b6a719a043fac9b5af9838660816392a09f","Cargo.toml.orig":"44ca1ae5d9b48743305b57f3367051289512037e7836b8b3693b68d48dec0483","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"1305bd79675db0194915d9bc91bd0b3cf9487bc1126e05bf46b48ab43edce44b","benches/bench.rs":"29a0bdb973848007d681e571c57487e21e1bfb7aed5980c2190dba354498b154","src/lib.rs":"e962338e1886873aa7c3399ec89aa5378ccbfed712b9690f043628079390a34f","src/u128_ext.rs":"498cc94f13805e551248fd82f47cc318f51d953a5002a9f8698858cd12fbae3c","tests/test.rs":"b22f8a8ed89edcbb4140b74f5edd7f2adf3cb0e363990dd6010cd6ebe0dc36b7"},"package":"8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"git": {
|
||||
"sha1": "af77385d0daf4d0e949e81f2588be2e44f69f086"
|
||||
},
|
||||
"path_in_vcs": ""
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
github: dtolnay
|
||||
@@ -0,0 +1,126 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
schedule: [cron: "40 1 * * *"]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
RUSTFLAGS: -Dwarnings
|
||||
|
||||
jobs:
|
||||
pre_ci:
|
||||
uses: dtolnay/.github/.github/workflows/pre_ci.yml@master
|
||||
|
||||
test:
|
||||
name: Rust ${{matrix.rust}}
|
||||
needs: pre_ci
|
||||
if: needs.pre_ci.outputs.continue
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
rust: [nightly, beta, stable, 1.86.0]
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
toolchain: ${{matrix.rust}}
|
||||
- name: Enable type layout randomization
|
||||
run: echo RUSTFLAGS=${RUSTFLAGS}\ -Zrandomize-layout >> $GITHUB_ENV
|
||||
if: matrix.rust == 'nightly'
|
||||
- run: cargo build
|
||||
- run: cargo test
|
||||
- run: cargo test --release
|
||||
- run: cargo build --no-default-features
|
||||
- run: cargo test --tests --no-default-features
|
||||
- run: cargo test --tests --no-default-features --release
|
||||
- run: cargo build --tests --features no-panic --release
|
||||
if: matrix.rust == 'nightly'
|
||||
- run: cargo bench --no-run
|
||||
if: matrix.rust == 'nightly'
|
||||
- uses: actions/upload-artifact@v6
|
||||
if: matrix.rust == 'nightly' && always()
|
||||
with:
|
||||
name: Cargo.lock
|
||||
path: Cargo.lock
|
||||
continue-on-error: true
|
||||
|
||||
msrv:
|
||||
name: Rust 1.68.0
|
||||
needs: pre_ci
|
||||
if: needs.pre_ci.outputs.continue
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: dtolnay/rust-toolchain@1.68
|
||||
- run: cargo build
|
||||
- run: cargo build --no-default-features
|
||||
|
||||
doc:
|
||||
name: Documentation
|
||||
needs: pre_ci
|
||||
if: needs.pre_ci.outputs.continue
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
env:
|
||||
RUSTDOCFLAGS: -Dwarnings
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: dtolnay/rust-toolchain@nightly
|
||||
- uses: dtolnay/install@cargo-docs-rs
|
||||
- run: cargo docs-rs
|
||||
|
||||
miri:
|
||||
name: Miri
|
||||
needs: pre_ci
|
||||
if: needs.pre_ci.outputs.continue
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: dtolnay/rust-toolchain@miri
|
||||
- run: cargo miri setup
|
||||
- run: cargo miri test
|
||||
env:
|
||||
MIRIFLAGS: -Zmiri-strict-provenance
|
||||
|
||||
clippy:
|
||||
name: Clippy
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name != 'pull_request'
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: dtolnay/rust-toolchain@clippy
|
||||
- run: cargo clippy --tests --benches -- -Dclippy::all -Dclippy::pedantic
|
||||
|
||||
fuzz:
|
||||
name: Fuzz
|
||||
needs: pre_ci
|
||||
if: needs.pre_ci.outputs.continue
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: dtolnay/rust-toolchain@nightly
|
||||
- uses: dtolnay/install@cargo-fuzz
|
||||
- run: cargo fuzz check
|
||||
|
||||
outdated:
|
||||
name: Outdated
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name != 'pull_request'
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- uses: dtolnay/install@cargo-outdated
|
||||
- run: cargo outdated --workspace --exit-code 1
|
||||
- run: cargo outdated --manifest-path fuzz/Cargo.toml --exit-code 1
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
###############################################################################
|
||||
# @generated
|
||||
# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To
|
||||
# regenerate this file, run the following:
|
||||
#
|
||||
# bazel run @@//third_party:vendor_crates
|
||||
###############################################################################
|
||||
|
||||
load("@rules_rust//cargo:defs.bzl", "cargo_toml_env_vars")
|
||||
load("@rules_rust//rust:defs.bzl", "rust_library")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
cargo_toml_env_vars(
|
||||
name = "cargo_toml_env_vars",
|
||||
src = "Cargo.toml",
|
||||
)
|
||||
|
||||
rust_library(
|
||||
name = "itoa",
|
||||
srcs = glob(
|
||||
include = ["**/*.rs"],
|
||||
allow_empty = False,
|
||||
),
|
||||
compile_data = glob(
|
||||
include = ["**"],
|
||||
allow_empty = True,
|
||||
exclude = [
|
||||
"**/* *",
|
||||
".tmp_git_root/**/*",
|
||||
"BUILD",
|
||||
"BUILD.bazel",
|
||||
"WORKSPACE",
|
||||
"WORKSPACE.bazel",
|
||||
],
|
||||
),
|
||||
crate_root = "src/lib.rs",
|
||||
edition = "2021",
|
||||
rustc_env_files = [
|
||||
":cargo_toml_env_vars",
|
||||
],
|
||||
rustc_flags = [
|
||||
"--cap-lints=allow",
|
||||
],
|
||||
tags = [
|
||||
"cargo-bazel",
|
||||
"crate-name=itoa",
|
||||
"manual",
|
||||
"noclippy",
|
||||
"norustfmt",
|
||||
],
|
||||
target_compatible_with = select({
|
||||
"@rules_rust//rust/platform:aarch64-apple-darwin": [],
|
||||
"@rules_rust//rust/platform:aarch64-apple-ios": [],
|
||||
"@rules_rust//rust/platform:aarch64-apple-ios-macabi": [],
|
||||
"@rules_rust//rust/platform:aarch64-apple-ios-sim": [],
|
||||
"@rules_rust//rust/platform:aarch64-linux-android": [],
|
||||
"@rules_rust//rust/platform:aarch64-pc-windows-msvc": [],
|
||||
"@rules_rust//rust/platform:aarch64-unknown-fuchsia": [],
|
||||
"@rules_rust//rust/platform:aarch64-unknown-linux-gnu": [],
|
||||
"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu": [],
|
||||
"@rules_rust//rust/platform:aarch64-unknown-none": [],
|
||||
"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710": [],
|
||||
"@rules_rust//rust/platform:aarch64-unknown-uefi": [],
|
||||
"@rules_rust//rust/platform:arm-unknown-linux-gnueabi": [],
|
||||
"@rules_rust//rust/platform:arm-unknown-linux-musleabi": [],
|
||||
"@rules_rust//rust/platform:armv7-linux-androideabi": [],
|
||||
"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi": [],
|
||||
"@rules_rust//rust/platform:i686-apple-darwin": [],
|
||||
"@rules_rust//rust/platform:i686-linux-android": [],
|
||||
"@rules_rust//rust/platform:i686-pc-windows-msvc": [],
|
||||
"@rules_rust//rust/platform:i686-unknown-freebsd": [],
|
||||
"@rules_rust//rust/platform:i686-unknown-linux-gnu": [],
|
||||
"@rules_rust//rust/platform:loongarch64-unknown-linux-gnu": [],
|
||||
"@rules_rust//rust/platform:mips-unknown-linux-gnu": [],
|
||||
"@rules_rust//rust/platform:powerpc-unknown-linux-gnu": [],
|
||||
"@rules_rust//rust/platform:riscv32imac-unknown-none-elf": [],
|
||||
"@rules_rust//rust/platform:riscv32imc-unknown-none-elf": [],
|
||||
"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu": [],
|
||||
"@rules_rust//rust/platform:riscv64gc-unknown-none-elf": [],
|
||||
"@rules_rust//rust/platform:s390x-unknown-linux-gnu": [],
|
||||
"@rules_rust//rust/platform:sparc64-unknown-linux-gnu": [],
|
||||
"@rules_rust//rust/platform:sparc64-unknown-netbsd": [],
|
||||
"@rules_rust//rust/platform:sparc64-unknown-openbsd": [],
|
||||
"@rules_rust//rust/platform:thumbv6m-none-eabi": [],
|
||||
"@rules_rust//rust/platform:thumbv7em-none-eabi": [],
|
||||
"@rules_rust//rust/platform:thumbv7em-none-eabihf": [],
|
||||
"@rules_rust//rust/platform:thumbv7m-none-eabi": [],
|
||||
"@rules_rust//rust/platform:thumbv8m.main-none-eabi": [],
|
||||
"@rules_rust//rust/platform:thumbv8m.main-none-eabihf": [],
|
||||
"@rules_rust//rust/platform:wasm32-unknown-emscripten": [],
|
||||
"@rules_rust//rust/platform:wasm32-unknown-unknown": [],
|
||||
"@rules_rust//rust/platform:wasm32-wasip1": [],
|
||||
"@rules_rust//rust/platform:wasm32-wasip1-threads": [],
|
||||
"@rules_rust//rust/platform:wasm32-wasip2": [],
|
||||
"@rules_rust//rust/platform:x86_64-apple-darwin": [],
|
||||
"@rules_rust//rust/platform:x86_64-apple-ios": [],
|
||||
"@rules_rust//rust/platform:x86_64-apple-ios-macabi": [],
|
||||
"@rules_rust//rust/platform:x86_64-linux-android": [],
|
||||
"@rules_rust//rust/platform:x86_64-pc-windows-msvc": [],
|
||||
"@rules_rust//rust/platform:x86_64-unknown-freebsd": [],
|
||||
"@rules_rust//rust/platform:x86_64-unknown-fuchsia": [],
|
||||
"@rules_rust//rust/platform:x86_64-unknown-linux-gnu": [],
|
||||
"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu": [],
|
||||
"@rules_rust//rust/platform:x86_64-unknown-none": [],
|
||||
"@rules_rust//rust/platform:x86_64-unknown-uefi": [],
|
||||
"//conditions:default": ["@platforms//:incompatible"],
|
||||
}),
|
||||
version = "1.0.18",
|
||||
)
|
||||
+460
@@ -0,0 +1,460 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "alloca"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5a7d05ea6aea7e9e64d25b9156ba2fee3fdd659e34e41063cd2fc7cd020d7f4"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[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.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "cast"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "ciborium"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e"
|
||||
dependencies = [
|
||||
"ciborium-io",
|
||||
"ciborium-ll",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ciborium-io"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757"
|
||||
|
||||
[[package]]
|
||||
name = "ciborium-ll"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9"
|
||||
dependencies = [
|
||||
"ciborium-io",
|
||||
"half",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
|
||||
|
||||
[[package]]
|
||||
name = "criterion"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "950046b2aa2492f9a536f5f4f9a3de7b9e2476e575e05bd6c333371add4d98f3"
|
||||
dependencies = [
|
||||
"alloca",
|
||||
"anes",
|
||||
"cast",
|
||||
"ciborium",
|
||||
"clap",
|
||||
"criterion-plot",
|
||||
"itertools",
|
||||
"num-traits",
|
||||
"oorandom",
|
||||
"page_size",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tinytemplate",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion-plot"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8d80a2f4f5b554395e47b5d8305bc3d27813bacb73493eb1001e8f76dae29ea"
|
||||
dependencies = [
|
||||
"cast",
|
||||
"itertools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "2.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crunchy",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.18"
|
||||
dependencies = [
|
||||
"criterion",
|
||||
"no-panic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.183"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||
|
||||
[[package]]
|
||||
name = "no-panic"
|
||||
version = "0.1.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f967505aabc8af5752d098c34146544a43684817cdba8f9725b292530cabbf53"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oorandom"
|
||||
version = "11.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e"
|
||||
|
||||
[[package]]
|
||||
name = "page_size"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
|
||||
|
||||
[[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 = "serde"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.149"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
|
||||
dependencies = [
|
||||
"itoa 1.0.17",
|
||||
"memchr",
|
||||
"serde",
|
||||
"serde_core",
|
||||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[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.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[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.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[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-link"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efbb2a062be311f2ba113ce66f697a4dc589f85e78a4aea276200804cea0ed87"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2021"
|
||||
rust-version = "1.68"
|
||||
name = "itoa"
|
||||
version = "1.0.18"
|
||||
authors = ["David Tolnay <dtolnay@gmail.com>"]
|
||||
build = false
|
||||
exclude = ["*.png"]
|
||||
autolib = false
|
||||
autobins = false
|
||||
autoexamples = false
|
||||
autotests = false
|
||||
autobenches = false
|
||||
description = "Fast integer primitive to string conversion"
|
||||
documentation = "https://docs.rs/itoa"
|
||||
readme = "README.md"
|
||||
keywords = ["integer"]
|
||||
categories = [
|
||||
"value-formatting",
|
||||
"no-std",
|
||||
"no-std::no-alloc",
|
||||
]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/dtolnay/itoa"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
rustdoc-args = [
|
||||
"--generate-link-to-definition",
|
||||
"--generate-macro-expansion",
|
||||
"--extern-html-root-url=core=https://doc.rust-lang.org",
|
||||
"--extern-html-root-url=alloc=https://doc.rust-lang.org",
|
||||
"--extern-html-root-url=std=https://doc.rust-lang.org",
|
||||
]
|
||||
|
||||
[lib]
|
||||
name = "itoa"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[[test]]
|
||||
name = "test"
|
||||
path = "tests/test.rs"
|
||||
|
||||
[[bench]]
|
||||
name = "bench"
|
||||
path = "benches/bench.rs"
|
||||
harness = false
|
||||
|
||||
[dependencies.no-panic]
|
||||
version = "0.1"
|
||||
optional = true
|
||||
|
||||
[target."cfg(not(miri))".dev-dependencies.criterion]
|
||||
version = "0.8"
|
||||
default-features = false
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
[package]
|
||||
name = "itoa"
|
||||
version = "1.0.18"
|
||||
authors = ["David Tolnay <dtolnay@gmail.com>"]
|
||||
categories = ["value-formatting", "no-std", "no-std::no-alloc"]
|
||||
description = "Fast integer primitive to string conversion"
|
||||
documentation = "https://docs.rs/itoa"
|
||||
edition = "2021"
|
||||
exclude = ["*.png"]
|
||||
keywords = ["integer"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/dtolnay/itoa"
|
||||
rust-version = "1.68"
|
||||
|
||||
[dependencies]
|
||||
no-panic = { version = "0.1", optional = true }
|
||||
|
||||
[target.'cfg(not(miri))'.dev-dependencies]
|
||||
criterion = { version = "0.8", default-features = false }
|
||||
|
||||
[[bench]]
|
||||
name = "bench"
|
||||
harness = false
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
rustdoc-args = [
|
||||
"--generate-link-to-definition",
|
||||
"--generate-macro-expansion",
|
||||
"--extern-html-root-url=core=https://doc.rust-lang.org",
|
||||
"--extern-html-root-url=alloc=https://doc.rust-lang.org",
|
||||
"--extern-html-root-url=std=https://doc.rust-lang.org",
|
||||
]
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
itoa
|
||||
====
|
||||
|
||||
[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/itoa-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/itoa)
|
||||
[<img alt="crates.io" src="https://img.shields.io/crates/v/itoa.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/itoa)
|
||||
[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-itoa-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/itoa)
|
||||
[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/dtolnay/itoa/ci.yml?branch=master&style=for-the-badge" height="20">](https://github.com/dtolnay/itoa/actions?query=branch%3Amaster)
|
||||
|
||||
This crate provides a fast conversion of integer primitives to decimal strings.
|
||||
The implementation comes straight from [libcore] but avoids the performance
|
||||
penalty of going through [`core::fmt::Formatter`].
|
||||
|
||||
See also [`zmij`] for printing floating point primitives.
|
||||
|
||||
[libcore]: https://github.com/rust-lang/rust/blob/1.92.0/library/core/src/fmt/num.rs#L190-L253
|
||||
[`core::fmt::Formatter`]: https://doc.rust-lang.org/std/fmt/struct.Formatter.html
|
||||
[`zmij`]: https://github.com/dtolnay/zmij
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
itoa = "1.0"
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## Example
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let mut buffer = itoa::Buffer::new();
|
||||
let printed = buffer.format(128u64);
|
||||
assert_eq!(printed, "128");
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## Performance
|
||||
|
||||
The [itoa-benchmark] compares this library and other Rust integer formatting
|
||||
implementations across a range of integer sizes. The vertical axis in this chart
|
||||
shows nanoseconds taken by a single execution of
|
||||
`itoa::Buffer::new().format(value)` so a lower result indicates a faster
|
||||
library.
|
||||
|
||||
[itoa-benchmark]: https://github.com/dtolnay/itoa-benchmark
|
||||
|
||||

|
||||
|
||||
<br>
|
||||
|
||||
#### License
|
||||
|
||||
<sup>
|
||||
Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
|
||||
2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
|
||||
</sup>
|
||||
|
||||
<br>
|
||||
|
||||
<sub>
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted
|
||||
for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
|
||||
be dual licensed as above, without any additional terms or conditions.
|
||||
</sub>
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use std::fmt::Display;
|
||||
use std::hint;
|
||||
use std::io::Write;
|
||||
|
||||
fn do_bench(c: &mut Criterion, group_name: &str, int: impl itoa::Integer + Display) {
|
||||
let mut group = c.benchmark_group(group_name);
|
||||
group.bench_function("itoa", |b| {
|
||||
let mut buf = itoa::Buffer::new();
|
||||
b.iter(move || {
|
||||
let int = hint::black_box(int);
|
||||
let formatted = buf.format(int);
|
||||
hint::black_box(formatted);
|
||||
});
|
||||
});
|
||||
group.bench_function("std::fmt", |b| {
|
||||
let mut buf = Vec::with_capacity(20);
|
||||
b.iter(|| {
|
||||
buf.clear();
|
||||
let int = hint::black_box(int);
|
||||
write!(&mut buf, "{int}").unwrap();
|
||||
hint::black_box(buf.as_slice());
|
||||
});
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
|
||||
fn bench(c: &mut Criterion) {
|
||||
do_bench(c, "u64[0]", 0u64);
|
||||
do_bench(c, "u64[half]", u64::from(u32::MAX));
|
||||
do_bench(c, "u64[max]", u64::MAX);
|
||||
|
||||
do_bench(c, "i16[0]", 0i16);
|
||||
do_bench(c, "i16[min]", i16::MIN);
|
||||
|
||||
do_bench(c, "u128[0]", 0u128);
|
||||
do_bench(c, "u128[max]", u128::MAX);
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench);
|
||||
criterion_main!(benches);
|
||||
+466
@@ -0,0 +1,466 @@
|
||||
//! [![github]](https://github.com/dtolnay/itoa) [![crates-io]](https://crates.io/crates/itoa) [![docs-rs]](https://docs.rs/itoa)
|
||||
//!
|
||||
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
|
||||
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
|
||||
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
|
||||
//!
|
||||
//! <br>
|
||||
//!
|
||||
//! This crate provides a fast conversion of integer primitives to decimal
|
||||
//! strings. The implementation comes straight from [libcore] but avoids the
|
||||
//! performance penalty of going through [`core::fmt::Formatter`].
|
||||
//!
|
||||
//! See also [`zmij`] for printing floating point primitives.
|
||||
//!
|
||||
//! [libcore]: https://github.com/rust-lang/rust/blob/1.92.0/library/core/src/fmt/num.rs#L190-L253
|
||||
//! [`zmij`]: https://github.com/dtolnay/zmij
|
||||
//!
|
||||
//! # Example
|
||||
//!
|
||||
//! ```
|
||||
//! fn main() {
|
||||
//! let mut buffer = itoa::Buffer::new();
|
||||
//! let printed = buffer.format(128u64);
|
||||
//! assert_eq!(printed, "128");
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! # Performance
|
||||
//!
|
||||
//! The [itoa-benchmark] compares this library and other Rust integer formatting
|
||||
//! implementations across a range of integer sizes. The vertical axis in this
|
||||
//! chart shows nanoseconds taken by a single execution of
|
||||
//! `itoa::Buffer::new().format(value)` so a lower result indicates a faster
|
||||
//! library.
|
||||
//!
|
||||
//! [itoa-benchmark]: https://github.com/dtolnay/itoa-benchmark
|
||||
//!
|
||||
//! 
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/itoa/1.0.18")]
|
||||
#![no_std]
|
||||
#![allow(
|
||||
clippy::cast_lossless,
|
||||
clippy::cast_possible_truncation,
|
||||
clippy::cast_sign_loss,
|
||||
clippy::expl_impl_clone_on_copy,
|
||||
clippy::identity_op,
|
||||
clippy::items_after_statements,
|
||||
clippy::must_use_candidate,
|
||||
clippy::needless_doctest_main,
|
||||
clippy::unreadable_literal
|
||||
)]
|
||||
|
||||
mod u128_ext;
|
||||
|
||||
use core::hint;
|
||||
use core::mem::{self, MaybeUninit};
|
||||
use core::str;
|
||||
#[cfg(feature = "no-panic")]
|
||||
use no_panic::no_panic;
|
||||
|
||||
/// A correctly sized stack allocation for the formatted integer to be written
|
||||
/// into.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let mut buffer = itoa::Buffer::new();
|
||||
/// let printed = buffer.format(1234);
|
||||
/// assert_eq!(printed, "1234");
|
||||
/// ```
|
||||
pub struct Buffer {
|
||||
bytes: [MaybeUninit<u8>; i128::MAX_STR_LEN],
|
||||
}
|
||||
|
||||
impl Default for Buffer {
|
||||
#[inline]
|
||||
fn default() -> Buffer {
|
||||
Buffer::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Copy for Buffer {}
|
||||
|
||||
#[allow(clippy::non_canonical_clone_impl)]
|
||||
impl Clone for Buffer {
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
Buffer::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Buffer {
|
||||
/// This is a cheap operation; you don't need to worry about reusing buffers
|
||||
/// for efficiency.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "no-panic", no_panic)]
|
||||
pub fn new() -> Buffer {
|
||||
let bytes = [MaybeUninit::<u8>::uninit(); i128::MAX_STR_LEN];
|
||||
Buffer { bytes }
|
||||
}
|
||||
|
||||
/// Print an integer into this buffer and return a reference to its string
|
||||
/// representation within the buffer.
|
||||
#[cfg_attr(feature = "no-panic", no_panic)]
|
||||
pub fn format<I: Integer>(&mut self, i: I) -> &str {
|
||||
let buf_ptr = self.bytes.as_mut_ptr().cast::<I::Buffer>();
|
||||
let string = i.write(unsafe { &mut *buf_ptr });
|
||||
if string.len() > I::MAX_STR_LEN {
|
||||
unsafe { hint::unreachable_unchecked() };
|
||||
}
|
||||
string
|
||||
}
|
||||
}
|
||||
|
||||
/// An integer that can be written into an [`itoa::Buffer`][Buffer].
|
||||
///
|
||||
/// This trait is sealed and cannot be implemented for types outside of itoa.
|
||||
pub trait Integer: private::Sealed {
|
||||
/// The maximum length of string that formatting an integer of this type can
|
||||
/// produce on the current target platform.
|
||||
const MAX_STR_LEN: usize;
|
||||
}
|
||||
|
||||
// Seal to prevent downstream implementations of the Integer trait.
|
||||
mod private {
|
||||
#[doc(hidden)]
|
||||
pub trait Sealed: Copy {
|
||||
#[doc(hidden)]
|
||||
type Buffer: 'static;
|
||||
fn write(self, buf: &mut Self::Buffer) -> &str;
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_Integer {
|
||||
($Signed:ident, $Unsigned:ident) => {
|
||||
const _: () = {
|
||||
assert!($Signed::MIN < 0, "need signed");
|
||||
assert!($Unsigned::MIN == 0, "need unsigned");
|
||||
assert!($Signed::BITS == $Unsigned::BITS, "need counterparts");
|
||||
};
|
||||
|
||||
impl Integer for $Unsigned {
|
||||
const MAX_STR_LEN: usize = $Unsigned::MAX.ilog10() as usize + 1;
|
||||
}
|
||||
|
||||
impl private::Sealed for $Unsigned {
|
||||
type Buffer = [MaybeUninit<u8>; Self::MAX_STR_LEN];
|
||||
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "no-panic", no_panic)]
|
||||
fn write(self, buf: &mut Self::Buffer) -> &str {
|
||||
let offset = Unsigned::fmt(self, buf);
|
||||
// SAFETY: Starting from `offset`, all elements of the slice have been set.
|
||||
unsafe { slice_buffer_to_str(buf, offset) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Integer for $Signed {
|
||||
const MAX_STR_LEN: usize = $Signed::MAX.ilog10() as usize + 2;
|
||||
}
|
||||
|
||||
impl private::Sealed for $Signed {
|
||||
type Buffer = [MaybeUninit<u8>; Self::MAX_STR_LEN];
|
||||
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "no-panic", no_panic)]
|
||||
fn write(self, buf: &mut Self::Buffer) -> &str {
|
||||
let mut offset = Self::MAX_STR_LEN - $Unsigned::MAX_STR_LEN;
|
||||
offset += Unsigned::fmt(
|
||||
self.unsigned_abs(),
|
||||
(&mut buf[offset..]).try_into().unwrap(),
|
||||
);
|
||||
if self < 0 {
|
||||
offset -= 1;
|
||||
buf[offset].write(b'-');
|
||||
}
|
||||
// SAFETY: Starting from `offset`, all elements of the slice have been set.
|
||||
unsafe { slice_buffer_to_str(buf, offset) }
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_Integer!(i8, u8);
|
||||
impl_Integer!(i16, u16);
|
||||
impl_Integer!(i32, u32);
|
||||
impl_Integer!(i64, u64);
|
||||
impl_Integer!(i128, u128);
|
||||
|
||||
macro_rules! impl_Integer_size {
|
||||
($t:ty as $primitive:ident #[cfg(target_pointer_width = $width:literal)]) => {
|
||||
#[cfg(target_pointer_width = $width)]
|
||||
impl Integer for $t {
|
||||
const MAX_STR_LEN: usize = <$primitive as Integer>::MAX_STR_LEN;
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = $width)]
|
||||
impl private::Sealed for $t {
|
||||
type Buffer = <$primitive as private::Sealed>::Buffer;
|
||||
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "no-panic", no_panic)]
|
||||
fn write(self, buf: &mut Self::Buffer) -> &str {
|
||||
(self as $primitive).write(buf)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_Integer_size!(isize as i16 #[cfg(target_pointer_width = "16")]);
|
||||
impl_Integer_size!(usize as u16 #[cfg(target_pointer_width = "16")]);
|
||||
impl_Integer_size!(isize as i32 #[cfg(target_pointer_width = "32")]);
|
||||
impl_Integer_size!(usize as u32 #[cfg(target_pointer_width = "32")]);
|
||||
impl_Integer_size!(isize as i64 #[cfg(target_pointer_width = "64")]);
|
||||
impl_Integer_size!(usize as u64 #[cfg(target_pointer_width = "64")]);
|
||||
|
||||
#[repr(C, align(2))]
|
||||
struct DecimalPairs([u8; 200]);
|
||||
|
||||
// The string of all two-digit numbers in range 00..99 is used as a lookup table.
|
||||
static DECIMAL_PAIRS: DecimalPairs = DecimalPairs(
|
||||
*b"0001020304050607080910111213141516171819\
|
||||
2021222324252627282930313233343536373839\
|
||||
4041424344454647484950515253545556575859\
|
||||
6061626364656667686970717273747576777879\
|
||||
8081828384858687888990919293949596979899",
|
||||
);
|
||||
|
||||
// Returns {value / 100, value % 100} correct for values of up to 4 digits.
|
||||
fn divmod100(value: u32) -> (u32, u32) {
|
||||
debug_assert!(value < 10_000);
|
||||
const EXP: u32 = 19; // 19 is faster or equal to 12 even for 3 digits.
|
||||
const SIG: u32 = (1 << EXP) / 100 + 1;
|
||||
let div = (value * SIG) >> EXP; // value / 100
|
||||
(div, value - div * 100)
|
||||
}
|
||||
|
||||
/// This function converts a slice of ascii characters into a `&str` starting
|
||||
/// from `offset`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// `buf` content starting from `offset` index MUST BE initialized and MUST BE
|
||||
/// ascii characters.
|
||||
#[cfg_attr(feature = "no-panic", no_panic)]
|
||||
unsafe fn slice_buffer_to_str(buf: &[MaybeUninit<u8>], offset: usize) -> &str {
|
||||
// SAFETY: `offset` is always included between 0 and `buf`'s length.
|
||||
let written = unsafe { buf.get_unchecked(offset..) };
|
||||
// SAFETY: (`assume_init_ref`) All buf content since offset is set.
|
||||
// SAFETY: (`from_utf8_unchecked`) Writes use ASCII from the lookup table exclusively.
|
||||
unsafe { str::from_utf8_unchecked(&*(written as *const [MaybeUninit<u8>] as *const [u8])) }
|
||||
}
|
||||
|
||||
trait Unsigned: Integer {
|
||||
fn fmt(self, buf: &mut Self::Buffer) -> usize;
|
||||
}
|
||||
|
||||
macro_rules! impl_Unsigned {
|
||||
($Unsigned:ident) => {
|
||||
impl Unsigned for $Unsigned {
|
||||
#[cfg_attr(feature = "no-panic", no_panic)]
|
||||
fn fmt(self, buf: &mut Self::Buffer) -> usize {
|
||||
// Count the number of bytes in buf that are not initialized.
|
||||
let mut offset = buf.len();
|
||||
// Consume the least-significant decimals from a working copy.
|
||||
let mut remain = self;
|
||||
|
||||
// Format per four digits from the lookup table.
|
||||
// Four digits need a 16-bit $Unsigned or wider.
|
||||
while mem::size_of::<Self>() > 1
|
||||
&& remain
|
||||
> 999
|
||||
.try_into()
|
||||
.expect("branch is not hit for types that cannot fit 999 (u8)")
|
||||
{
|
||||
offset -= 4;
|
||||
|
||||
// pull two pairs
|
||||
let scale: Self = 1_00_00
|
||||
.try_into()
|
||||
.expect("branch is not hit for types that cannot fit 1E4 (u8)");
|
||||
let quad = remain % scale;
|
||||
remain /= scale;
|
||||
let (pair1, pair2) = divmod100(quad as u32);
|
||||
unsafe {
|
||||
buf[offset + 0]
|
||||
.write(*DECIMAL_PAIRS.0.get_unchecked(pair1 as usize * 2 + 0));
|
||||
buf[offset + 1]
|
||||
.write(*DECIMAL_PAIRS.0.get_unchecked(pair1 as usize * 2 + 1));
|
||||
buf[offset + 2]
|
||||
.write(*DECIMAL_PAIRS.0.get_unchecked(pair2 as usize * 2 + 0));
|
||||
buf[offset + 3]
|
||||
.write(*DECIMAL_PAIRS.0.get_unchecked(pair2 as usize * 2 + 1));
|
||||
}
|
||||
}
|
||||
|
||||
// Format per two digits from the lookup table.
|
||||
if remain > 9 {
|
||||
offset -= 2;
|
||||
|
||||
let (last, pair) = divmod100(remain as u32);
|
||||
remain = last as Self;
|
||||
unsafe {
|
||||
buf[offset + 0]
|
||||
.write(*DECIMAL_PAIRS.0.get_unchecked(pair as usize * 2 + 0));
|
||||
buf[offset + 1]
|
||||
.write(*DECIMAL_PAIRS.0.get_unchecked(pair as usize * 2 + 1));
|
||||
}
|
||||
}
|
||||
|
||||
// Format the last remaining digit, if any.
|
||||
if remain != 0 || self == 0 {
|
||||
offset -= 1;
|
||||
|
||||
// Either the compiler sees that remain < 10, or it prevents
|
||||
// a boundary check up next.
|
||||
let last = remain as u8 & 15;
|
||||
buf[offset].write(b'0' + last);
|
||||
// not used: remain = 0;
|
||||
}
|
||||
|
||||
offset
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_Unsigned!(u8);
|
||||
impl_Unsigned!(u16);
|
||||
impl_Unsigned!(u32);
|
||||
impl_Unsigned!(u64);
|
||||
|
||||
impl Unsigned for u128 {
|
||||
#[cfg_attr(feature = "no-panic", no_panic)]
|
||||
fn fmt(self, buf: &mut Self::Buffer) -> usize {
|
||||
// Optimize common-case zero, which would also need special treatment due to
|
||||
// its "leading" zero.
|
||||
if self == 0 {
|
||||
let offset = buf.len() - 1;
|
||||
buf[offset].write(b'0');
|
||||
return offset;
|
||||
}
|
||||
// Take the 16 least-significant decimals.
|
||||
let (quot_1e16, mod_1e16) = div_rem_1e16(self);
|
||||
let (mut remain, mut offset) = if quot_1e16 == 0 {
|
||||
(mod_1e16, u128::MAX_STR_LEN)
|
||||
} else {
|
||||
// Write digits at buf[23..39].
|
||||
enc_16lsd::<{ u128::MAX_STR_LEN - 16 }>(buf, mod_1e16);
|
||||
|
||||
// Take another 16 decimals.
|
||||
let (quot2, mod2) = div_rem_1e16(quot_1e16);
|
||||
if quot2 == 0 {
|
||||
(mod2, u128::MAX_STR_LEN - 16)
|
||||
} else {
|
||||
// Write digits at buf[7..23].
|
||||
enc_16lsd::<{ u128::MAX_STR_LEN - 32 }>(buf, mod2);
|
||||
// Quot2 has at most 7 decimals remaining after two 1e16 divisions.
|
||||
(quot2 as u64, u128::MAX_STR_LEN - 32)
|
||||
}
|
||||
};
|
||||
|
||||
// Format per four digits from the lookup table.
|
||||
while remain > 999 {
|
||||
offset -= 4;
|
||||
|
||||
// pull two pairs
|
||||
let quad = remain % 1_00_00;
|
||||
remain /= 1_00_00;
|
||||
let (pair1, pair2) = divmod100(quad as u32);
|
||||
unsafe {
|
||||
buf[offset + 0].write(*DECIMAL_PAIRS.0.get_unchecked(pair1 as usize * 2 + 0));
|
||||
buf[offset + 1].write(*DECIMAL_PAIRS.0.get_unchecked(pair1 as usize * 2 + 1));
|
||||
buf[offset + 2].write(*DECIMAL_PAIRS.0.get_unchecked(pair2 as usize * 2 + 0));
|
||||
buf[offset + 3].write(*DECIMAL_PAIRS.0.get_unchecked(pair2 as usize * 2 + 1));
|
||||
}
|
||||
}
|
||||
|
||||
// Format per two digits from the lookup table.
|
||||
if remain > 9 {
|
||||
offset -= 2;
|
||||
|
||||
let (last, pair) = divmod100(remain as u32);
|
||||
remain = last as u64;
|
||||
unsafe {
|
||||
buf[offset + 0].write(*DECIMAL_PAIRS.0.get_unchecked(pair as usize * 2 + 0));
|
||||
buf[offset + 1].write(*DECIMAL_PAIRS.0.get_unchecked(pair as usize * 2 + 1));
|
||||
}
|
||||
}
|
||||
|
||||
// Format the last remaining digit, if any.
|
||||
if remain != 0 {
|
||||
offset -= 1;
|
||||
|
||||
// Either the compiler sees that remain < 10, or it prevents
|
||||
// a boundary check up next.
|
||||
let last = remain as u8 & 15;
|
||||
buf[offset].write(b'0' + last);
|
||||
// not used: remain = 0;
|
||||
}
|
||||
offset
|
||||
}
|
||||
}
|
||||
|
||||
// Encodes the 16 least-significant decimals of n into `buf[OFFSET..OFFSET + 16]`.
|
||||
#[cfg_attr(feature = "no-panic", no_panic)]
|
||||
fn enc_16lsd<const OFFSET: usize>(buf: &mut [MaybeUninit<u8>], n: u64) {
|
||||
// Consume the least-significant decimals from a working copy.
|
||||
let mut remain = n;
|
||||
|
||||
// Format per four digits from the lookup table.
|
||||
for quad_index in (1..4).rev() {
|
||||
// pull two pairs
|
||||
let quad = remain % 1_00_00;
|
||||
remain /= 1_00_00;
|
||||
let (pair1, pair2) = divmod100(quad as u32);
|
||||
unsafe {
|
||||
buf[quad_index * 4 + OFFSET + 0]
|
||||
.write(*DECIMAL_PAIRS.0.get_unchecked(pair1 as usize * 2 + 0));
|
||||
buf[quad_index * 4 + OFFSET + 1]
|
||||
.write(*DECIMAL_PAIRS.0.get_unchecked(pair1 as usize * 2 + 1));
|
||||
buf[quad_index * 4 + OFFSET + 2]
|
||||
.write(*DECIMAL_PAIRS.0.get_unchecked(pair2 as usize * 2 + 0));
|
||||
buf[quad_index * 4 + OFFSET + 3]
|
||||
.write(*DECIMAL_PAIRS.0.get_unchecked(pair2 as usize * 2 + 1));
|
||||
}
|
||||
}
|
||||
|
||||
// final two pairs
|
||||
let (pair1, pair2) = divmod100(remain as u32);
|
||||
unsafe {
|
||||
buf[OFFSET + 0].write(*DECIMAL_PAIRS.0.get_unchecked(pair1 as usize * 2 + 0));
|
||||
buf[OFFSET + 1].write(*DECIMAL_PAIRS.0.get_unchecked(pair1 as usize * 2 + 1));
|
||||
buf[OFFSET + 2].write(*DECIMAL_PAIRS.0.get_unchecked(pair2 as usize * 2 + 0));
|
||||
buf[OFFSET + 3].write(*DECIMAL_PAIRS.0.get_unchecked(pair2 as usize * 2 + 1));
|
||||
}
|
||||
}
|
||||
|
||||
// Euclidean division plus remainder with constant 1E16 basically consumes 16
|
||||
// decimals from n.
|
||||
//
|
||||
// The integer division algorithm is based on the following paper:
|
||||
//
|
||||
// T. Granlund and P. Montgomery, “Division by Invariant Integers Using Multiplication”
|
||||
// in Proc. of the SIGPLAN94 Conference on Programming Language Design and
|
||||
// Implementation, 1994, pp. 61–72
|
||||
//
|
||||
#[cfg_attr(feature = "no-panic", no_panic)]
|
||||
fn div_rem_1e16(n: u128) -> (u128, u64) {
|
||||
const D: u128 = 1_0000_0000_0000_0000;
|
||||
// The check inlines well with the caller flow.
|
||||
if n < D {
|
||||
return (0, n as u64);
|
||||
}
|
||||
|
||||
// These constant values are computed with the CHOOSE_MULTIPLIER procedure
|
||||
// from the Granlund & Montgomery paper, using N=128, prec=128 and d=1E16.
|
||||
const M_HIGH: u128 = 76624777043294442917917351357515459181;
|
||||
const SH_POST: u8 = 51;
|
||||
|
||||
// n.widening_mul(M_HIGH).1 >> SH_POST
|
||||
let quot = u128_ext::mulhi(n, M_HIGH) >> SH_POST;
|
||||
let rem = n - quot * D;
|
||||
(quot, rem as u64)
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
#[cfg(feature = "no-panic")]
|
||||
use no_panic::no_panic;
|
||||
|
||||
/// Multiply unsigned 128 bit integers, return upper 128 bits of the result
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "no-panic", no_panic)]
|
||||
pub(crate) fn mulhi(x: u128, y: u128) -> u128 {
|
||||
let x_lo = x as u64;
|
||||
let x_hi = (x >> 64) as u64;
|
||||
let y_lo = y as u64;
|
||||
let y_hi = (y >> 64) as u64;
|
||||
|
||||
// handle possibility of overflow
|
||||
let carry = (u128::from(x_lo) * u128::from(y_lo)) >> 64;
|
||||
let m = u128::from(x_lo) * u128::from(y_hi) + carry;
|
||||
let high1 = m >> 64;
|
||||
|
||||
let m_lo = m as u64;
|
||||
let high2 = (u128::from(x_hi) * u128::from(y_lo) + u128::from(m_lo)) >> 64;
|
||||
|
||||
u128::from(x_hi) * u128::from(y_hi) + high1 + high2
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
macro_rules! test {
|
||||
($($name:ident($value:expr, $expected:expr))*) => {
|
||||
$(
|
||||
#[test]
|
||||
fn $name() {
|
||||
let mut buffer = itoa::Buffer::new();
|
||||
let s = buffer.format($value);
|
||||
assert_eq!(s, $expected);
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
test! {
|
||||
test_u64_0(0u64, "0")
|
||||
test_u64_half(u64::from(u32::MAX), "4294967295")
|
||||
test_u64_max(u64::MAX, "18446744073709551615")
|
||||
test_i64_min(i64::MIN, "-9223372036854775808")
|
||||
|
||||
test_i16_0(0i16, "0")
|
||||
test_i16_min(i16::MIN, "-32768")
|
||||
|
||||
test_u128_0(0u128, "0")
|
||||
test_u128_max(u128::MAX, "340282366920938463463374607431768211455")
|
||||
test_i128_min(i128::MIN, "-170141183460469231731687303715884105728")
|
||||
test_i128_max(i128::MAX, "170141183460469231731687303715884105727")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_max_str_len() {
|
||||
use itoa::Integer as _;
|
||||
|
||||
assert_eq!(i8::MAX_STR_LEN, 4);
|
||||
assert_eq!(u8::MAX_STR_LEN, 3);
|
||||
assert_eq!(i16::MAX_STR_LEN, 6);
|
||||
assert_eq!(u16::MAX_STR_LEN, 5);
|
||||
assert_eq!(i32::MAX_STR_LEN, 11);
|
||||
assert_eq!(u32::MAX_STR_LEN, 10);
|
||||
assert_eq!(i64::MAX_STR_LEN, 20);
|
||||
assert_eq!(u64::MAX_STR_LEN, 20);
|
||||
assert_eq!(i128::MAX_STR_LEN, 40);
|
||||
assert_eq!(u128::MAX_STR_LEN, 39);
|
||||
}
|
||||
Reference in new issue
Block a user