diff --git a/.github/copyright.sh b/.github/copyright.sh new file mode 100644 index 00000000..803aa51f --- /dev/null +++ b/.github/copyright.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# If there are new files with headers that can't match the conditions here, +# then the files can be ignored by an additional glob argument via the -g flag. +# For example: +# -g "!src/special_file.rs" +# -g "!src/special_directory" + +# Check all the standard Rust source files +output=$(rg "^// Copyright (19|20)[\d]{2} (.+ and )?the Kurbo Authors( and .+)?$\n^// SPDX-License-Identifier: Apache-2\.0 OR MIT$\n\n" --files-without-match --multiline -g "*.rs" .) + +if [ -n "$output" ]; then + echo -e "The following files lack the correct copyright header:\n" + echo $output + echo -e "\n\nPlease add the following header:\n" + echo "// Copyright $(date +%Y) the Kurbo Authors" + echo "// SPDX-License-Identifier: Apache-2.0 OR MIT" + echo -e "\n... rest of the file ...\n" + exit 1 +fi + +echo "All files have correct copyright headers." +exit 0 + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 67e83554..2a63d85f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,3 +1,46 @@ +env: + # We aim to always test with the latest stable Rust toolchain, however we pin to a specific + # version like 1.70. Note that we only specify MAJOR.MINOR and not PATCH so that bugfixes still + # come automatically. If the version specified here is no longer the latest stable version, + # then please feel free to submit a PR that adjusts it along with the potential clippy fixes. + RUST_STABLE_VER: "1.79" # In quotes because otherwise (e.g.) 1.70 would be interpreted as 1.7 + # The purpose of checking with the minimum supported Rust toolchain is to detect its staleness. + # If the compilation fails, then the version specified here needs to be bumped up to reality. + # Be sure to also update the rust-version property in the workspace Cargo.toml file, + # plus all the README.md files of the affected packages. + RUST_MIN_VER: "1.65" + # List of packages that will be checked with the minimum supported Rust version. + # This should be limited to packages that are intended for publishing. + RUST_MIN_VER_PKGS: "-p kurbo" + # List of features that depend on the standard library and will be excluded from no_std checks. + FEATURES_DEPENDING_ON_STD: "std,default" + + +# Rationale +# +# We don't run clippy with --all-targets because then even --lib and --bins are compiled with +# dev dependencies enabled, which does not match how they would be compiled by users. +# A dev dependency might enable a feature that we need for a regular dependency, +# and checking with --all-targets would not find our feature requirements lacking. +# This problem still applies to cargo resolver version 2. +# Thus we split all the targets into two steps, one with --lib --bins +# and another with --tests --benches --examples. +# Also, we can't give --lib --bins explicitly because then cargo will error on binary-only packages. +# Luckily the default behavior of cargo with no explicit targets is the same but without the error. +# +# We use cargo-hack for a similar reason. Cargo's --workspace will do feature unification across +# the whole workspace. While cargo-hack will instead check each workspace package separately. +# +# Using cargo-hack also allows us to more easily test the feature matrix of our packages. +# We use --each-feature & --optional-deps which will run a separate check for every feature. +# +# The MSRV jobs run only cargo check because different clippy versions can disagree on goals and +# running tests introduces dev dependencies which may require a higher MSRV than the bare package. +# +# For no_std checks we target x86_64-unknown-none, because this target doesn't support std +# and as such will error out if our dependency tree accidentally tries to use std. +# https://doc.rust-lang.org/stable/rustc/platform-support/x86_64-unknown-none.html + name: CI on: @@ -7,122 +50,197 @@ on: pull_request: jobs: - rustfmt: - runs-on: ubuntu-latest + fmt: name: cargo fmt + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: install stable toolchain uses: dtolnay/rust-toolchain@master with: - toolchain: "stable" + toolchain: ${{ env.RUST_STABLE_VER }} components: rustfmt - name: cargo fmt - run: cargo fmt --all -- --check + run: cargo fmt --all --check - test-stable: + - name: install ripgrep + run: | + sudo apt update + sudo apt install ripgrep + + - name: check copyright headers + run: bash .github/copyright.sh + + clippy-stable: + name: cargo clippy runs-on: ${{ matrix.os }} strategy: matrix: - os: [macOS-latest, windows-2019, ubuntu-latest] - name: cargo clippy+test + os: [windows-latest, macos-latest, ubuntu-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + + - name: restore cache + uses: Swatinem/rust-cache@v2 - name: install stable toolchain uses: dtolnay/rust-toolchain@master with: - toolchain: "stable" + toolchain: ${{ env.RUST_STABLE_VER }} + targets: x86_64-unknown-none components: clippy - - run: rustup target add thumbv7m-none-eabi + - name: install cargo-hack + uses: taiki-e/install-action@v2 + with: + tool: cargo-hack + + - name: cargo clippy (no_std) + run: cargo hack clippy --workspace --locked --optional-deps --each-feature --features libm --exclude-features ${{ env.FEATURES_DEPENDING_ON_STD }} --target x86_64-unknown-none -- -D warnings - name: cargo clippy - run: cargo clippy --all-features --all-targets -- -D warnings + run: cargo hack clippy --workspace --locked --optional-deps --each-feature --features std -- -D warnings - - name: cargo test - run: cargo test --all-features + - name: cargo clippy (auxiliary) + run: cargo hack clippy --workspace --locked --optional-deps --each-feature --features std --tests --benches --examples -- -D warnings - - name: Build with no default features - # Use no-std target to ensure we don't link to std. - run: cargo build --no-default-features --features libm --target thumbv7m-none-eabi + clippy-stable-wasm: + name: cargo clippy (wasm32) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 - - name: cargo test --features=serde - run: cargo test --features=serde + - name: restore cache + uses: Swatinem/rust-cache@v2 - test-stable-wasm: + - name: install stable toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.RUST_STABLE_VER }} + targets: wasm32-unknown-unknown + components: clippy + + - name: install cargo-hack + uses: taiki-e/install-action@v2 + with: + tool: cargo-hack + + - name: cargo clippy + run: cargo hack clippy --workspace --locked --target wasm32-unknown-unknown --optional-deps --each-feature --features std -- -D warnings + + - name: cargo clippy (auxiliary) + run: cargo hack clippy --workspace --locked --target wasm32-unknown-unknown --optional-deps --each-feature --features std --tests --benches --examples -- -D warnings + + test-stable: + name: cargo test runs-on: ${{ matrix.os }} strategy: matrix: - os: [macOS-latest, windows-2019, ubuntu-latest] - - name: cargo clippy+test (wasm32) + os: [windows-latest, macos-latest, ubuntu-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + + - name: restore cache + uses: Swatinem/rust-cache@v2 - name: install stable toolchain uses: dtolnay/rust-toolchain@master with: - toolchain: "stable" - target: wasm32-unknown-unknown - components: clippy + toolchain: ${{ env.RUST_STABLE_VER }} - - name: cargo clippy - run: cargo clippy --all-features --all-targets --target wasm32-unknown-unknown -- -D warnings - - # TODO: Find a way to make tests work. Until then the tests are merely compiled. - - name: cargo test compile - run: cargo test --all-features --no-run --target wasm32-unknown-unknown + - name: cargo test + run: cargo test --workspace --locked --all-features - test-msrv: + test-stable-wasm: + name: cargo test (wasm32) runs-on: ubuntu-latest - name: cargo test msrv steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - name: install msrv toolchain + - name: restore cache + uses: Swatinem/rust-cache@v2 + + - name: install stable toolchain uses: dtolnay/rust-toolchain@master with: - toolchain: "1.65" + toolchain: ${{ env.RUST_STABLE_VER }} + targets: wasm32-unknown-unknown - - name: cargo test - run: cargo test --all-features + # TODO: Find a way to make tests work. Until then the tests are merely compiled. + - name: cargo test compile + run: cargo test --workspace --locked --target wasm32-unknown-unknown --all-features --no-run - test-nightly: + check-msrv: + name: cargo check (msrv) runs-on: ${{ matrix.os }} strategy: matrix: - os: [macOS-latest, windows-2019, ubuntu-latest] - name: cargo test nightly + os: [windows-latest, macos-latest, ubuntu-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - name: install nightly toolchain + - name: restore cache + uses: Swatinem/rust-cache@v2 + + - name: install msrv toolchain uses: dtolnay/rust-toolchain@master with: - toolchain: "nightly" + toolchain: ${{ env.RUST_MIN_VER }} + targets: x86_64-unknown-none - - name: cargo test - run: cargo test --all-features + - name: install cargo-hack + uses: taiki-e/install-action@v2 + with: + tool: cargo-hack - check-docs: - name: Docs - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [macOS-latest, windows-2019, ubuntu-latest] + - name: cargo check (no_std) + run: cargo hack check ${{ env.RUST_MIN_VER_PKGS }} --locked --optional-deps --each-feature --features libm --exclude-features ${{ env.FEATURES_DEPENDING_ON_STD }} --target x86_64-unknown-none + + - name: cargo check + run: cargo hack check ${{ env.RUST_MIN_VER_PKGS }} --locked --optional-deps --each-feature --features std + + check-msrv-wasm: + name: cargo check (msrv) (wasm32) + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - name: install stable toolchain + - name: restore cache + uses: Swatinem/rust-cache@v2 + + - name: install msrv toolchain uses: dtolnay/rust-toolchain@master with: - toolchain: "stable" + toolchain: ${{ env.RUST_MIN_VER }} + targets: wasm32-unknown-unknown + + - name: install cargo-hack + uses: taiki-e/install-action@v2 + with: + tool: cargo-hack + + - name: cargo check + run: cargo hack check ${{ env.RUST_MIN_VER_PKGS }} --locked --target wasm32-unknown-unknown --optional-deps --each-feature --features std + + doc: + name: cargo doc + # NOTE: We don't have any platform specific docs in this workspace, so we only run on Ubuntu. + # If we get per-platform docs (win/macos/linux/wasm32/..) then doc jobs should match that. + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: restore cache + uses: Swatinem/rust-cache@v2 + + - name: install nightly toolchain + uses: dtolnay/rust-toolchain@nightly + # We test documentation using nightly to match docs.rs. This prevents potential breakages - name: cargo doc - run: cargo doc --all-features --document-private-items + run: cargo doc --workspace --locked --all-features --no-deps --document-private-items -Zunstable-options -Zrustdoc-scrape-examples # If this fails, consider changing your text or adding something to .typos.toml typos: diff --git a/.gitignore b/.gitignore index 84abe005..8dce13fa 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,3 @@ /target **/*.rs.bk -Cargo.lock diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000..55ce8e04 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,349 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "dyn-clone" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "kurbo" +version = "0.11.0" +dependencies = [ + "arrayvec", + "getrandom", + "libm", + "mint", + "rand", + "schemars", + "serde", + "smallvec", +] + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "mint" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e53debba6bda7a793e5f99b8dacf19e626084f525f7829104ba9898f367d85ff" + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "ppv-lite86" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee4364d9f3b902ef14fab8a1ddffb783a1cb6b4bba3bfc1fa3922732c7de97f" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "schemars" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", + "smallvec", +] + +[[package]] +name = "schemars_derive" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + +[[package]] +name = "serde" +version = "1.0.204" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.204" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +dependencies = [ + "serde", +] + +[[package]] +name = "syn" +version = "2.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "zerocopy" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854e949ac82d619ee9a14c66a1b674ac730422372ccb759ce0c39cabcf2bf8e6" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index a0641979..6aa819b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,33 +24,33 @@ serde=["smallvec/serde", "dep:serde"] schemars=["schemars/smallvec", "dep:schemars"] [dependencies] -smallvec = "1.10" +smallvec = "1.13.2" [dependencies.arrayvec] -version = "0.7.1" +version = "0.7.4" default-features = false [dependencies.libm] -version = "0.2.6" +version = "0.2.8" optional = true [dependencies.mint] -version = "0.5.1" +version = "0.5.9" optional = true [dependencies.schemars] -version = "0.8.6" +version = "0.8.21" optional = true [dependencies.serde] -version = "1.0.105" +version = "1.0.204" optional = true default-features = false features = ["alloc", "derive"] # This is used for research but not really needed; maybe refactor. [dev-dependencies] -rand = "0.8.0" +rand = "0.8.5" [target.'cfg(target_arch="wasm32")'.dev-dependencies] -getrandom = { version = "0.2.0", features = ["js"] } +getrandom = { version = "0.2.15", features = ["js"] }