diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 65ea2a9..a997e44 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -1,4 +1,4 @@ -# This file is autogenerated by maturin v1.3.2 +# This file is autogenerated by maturin # To update, run # # maturin generate-ci github @@ -10,9 +10,9 @@ on: branches: - main tags: - - '*' + - "*" pull_request: - branches: [ main ] + branches: [main] workflow_dispatch: permissions: @@ -22,39 +22,30 @@ env: CARGO_TERM_COLOR: always jobs: - test: name: Tests strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] + python: ["3.10", "3.x"] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - - uses: actions-rs/cargo@v1 + - uses: actions/checkout@v7 + - uses: actions/setup-python@v7 with: - command: test + python-version: ${{ matrix.python }} + - uses: dtolnay/rust-toolchain@stable + - run: cargo test fmt: name: Rustfmt runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@stable with: - profile: minimal - toolchain: stable - override: true - - run: rustup component add rustfmt - - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check + components: rustfmt + - run: cargo fmt --all -- --check clippy: name: Build Clippy @@ -63,52 +54,46 @@ jobs: matrix: rust: - stable - - 1.72.0 + - 1.98.0 steps: - - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@master with: - profile: minimal toolchain: ${{ matrix.rust }} - override: true - - run: rustup component add clippy - - uses: actions-rs/cargo@v1 - with: - command: clippy - args: -- -D warnings + components: clippy + - run: cargo clippy -- -D warnings linux: runs-on: ${{ matrix.platform.runner }} strategy: - matrix: + matrix: platform: - - runner: ubuntu-latest + - runner: ubuntu-24.04 target: x86_64 - - runner: ubuntu-latest + - runner: ubuntu-24.04 target: x86 - # skipping until ring update/fix compile issue: include/ring-core/asm_base.h:73:2: error: #error "ARM assembler must define __ARM_ARCH" - # - runner: ubuntu-latest - # target: aarch64 - - runner: ubuntu-latest + - runner: ubuntu-24.04 + target: aarch64 + - runner: ubuntu-24.04 target: armv7 - - runner: ubuntu-latest + - runner: ubuntu-24.04 target: s390x - - runner: ubuntu-latest + - runner: ubuntu-24.04 target: ppc64le steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v7 + - uses: actions/setup-python@v7 with: python-version: 3.x - name: Build wheels - uses: PyO3/maturin-action@v1 + uses: PyO3/maturin-action@v1.51.0 with: target: ${{ matrix.platform.target }} args: --release --out dist - sccache: 'true' + sccache: "true" manylinux: auto - name: Upload wheels - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: wheels-linux-${{ matrix.platform.target }} path: dist @@ -118,29 +103,28 @@ jobs: strategy: matrix: platform: - - runner: ubuntu-latest + - runner: ubuntu-24.04 target: x86_64 - - runner: ubuntu-latest + - runner: ubuntu-24.04 target: x86 - # skipping until ring update/fix compile issue: include/ring-core/asm_base.h:73:2: error: #error "ARM assembler must define __ARM_ARCH" - # - runner: ubuntu-latest - # target: aarch64 - - runner: ubuntu-latest + - runner: ubuntu-24.04 + target: aarch64 + - runner: ubuntu-24.04 target: armv7 steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v7 + - uses: actions/setup-python@v7 with: python-version: 3.x - name: Build wheels - uses: PyO3/maturin-action@v1 + uses: PyO3/maturin-action@v1.51.0 with: target: ${{ matrix.platform.target }} args: --release --out dist - sccache: 'true' + sccache: "true" manylinux: musllinux_1_2 - name: Upload wheels - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: wheels-musllinux-${{ matrix.platform.target }} path: dist @@ -150,24 +134,24 @@ jobs: strategy: matrix: platform: - - runner: windows-latest + - runner: windows-2025 target: x64 - - runner: windows-latest + - runner: windows-2025 target: x86 steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v7 + - uses: actions/setup-python@v7 with: python-version: 3.x architecture: ${{ matrix.platform.target }} - name: Build wheels - uses: PyO3/maturin-action@v1 + uses: PyO3/maturin-action@v1.51.0 with: target: ${{ matrix.platform.target }} args: --release --out dist - sccache: 'true' + sccache: "true" - name: Upload wheels - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: wheels-windows-${{ matrix.platform.target }} path: dist @@ -177,23 +161,23 @@ jobs: strategy: matrix: platform: - - runner: macos-12 + - runner: macos-26-intel target: x86_64 - - runner: macos-14 + - runner: macos-26 target: aarch64 steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v7 + - uses: actions/setup-python@v7 with: python-version: 3.x - name: Build wheels - uses: PyO3/maturin-action@v1 + uses: PyO3/maturin-action@v1.51.0 with: target: ${{ matrix.platform.target }} args: --release --out dist - sccache: 'true' + sccache: "true" - name: Upload wheels - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: wheels-macos-${{ matrix.platform.target }} path: dist @@ -201,14 +185,14 @@ jobs: sdist: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - name: Build sdist - uses: PyO3/maturin-action@v1 + uses: PyO3/maturin-action@v1.51.0 with: command: sdist args: --out dist - name: Upload sdist - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: wheels-sdist path: dist @@ -226,14 +210,14 @@ jobs: # Used to generate artifact attestation attestations: write steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 - name: Generate artifact attestation - uses: actions/attest-build-provenance@v1 + uses: actions/attest@v4 with: - subject-path: 'wheels-*/*' + subject-path: "wheels-*/*" - name: Publish to PyPI if: "startsWith(github.ref, 'refs/tags/')" - uses: PyO3/maturin-action@v1 + uses: PyO3/maturin-action@v1.51.0 env: MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }} with: @@ -246,11 +230,7 @@ jobs: needs: [release] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@stable - name: Publish run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 35ce42e..85b2d42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## v6.0.0 (2026-09-08) + +* General maintenance and improvements on GTFS data handling and algorithms [#206](https://github.com/gerardcl/renfe-cli/issues/206) + ## v5.2.0 (2024-10-03) * Publish Rust crate binary via crates.io [#202](https://github.com/gerardcl/renfe-cli/issues/202) diff --git a/Cargo.lock b/Cargo.lock index 70de2da..a0dede8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,68 +1,56 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] -name = "addr2line" -version = "0.24.1" +name = "android_system_properties" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" dependencies = [ - "gimli", + "libc", ] [[package]] -name = "adler2" -version = "2.0.0" +name = "atomic-waker" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] -name = "android-tzdata" -version = "0.1.1" +name = "autocfg" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] -name = "android_system_properties" -version = "0.1.5" +name = "aws-lc-rs" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +checksum = "b281d307588d634de920874890732659e2e7672f72b5e10e81badc1a8a83621e" dependencies = [ - "libc", + "aws-lc-sys", + "zeroize", ] [[package]] -name = "autocfg" -version = "1.4.0" +name = "aws-lc-sys" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "9bff6c3b54fad79a2e60b8102caf565819711497c1f5f092f49508e2f5c31b27" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", + "pkg-config", +] [[package]] -name = "backtrace" -version = "0.3.74" +name = "base16ct" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets", -] +checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6" [[package]] name = "base64" @@ -71,111 +59,126 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] -name = "base64ct" -version = "1.6.0" +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] name = "block-buffer" -version = "0.10.4" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bytemuck" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" - -[[package]] -name = "byteorder" -version = "1.5.0" +version = "1.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797" [[package]] name = "bytes" -version = "1.7.2" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] -name = "bzip2" -version = "0.4.4" +name = "cc" +version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273" dependencies = [ - "bzip2-sys", + "find-msvc-tools", + "jobserver", "libc", + "shlex", ] [[package]] -name = "bzip2-sys" -version = "0.1.11+1.0.8" +name = "cfg-if" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" -dependencies = [ - "cc", - "libc", - "pkg-config", -] +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] -name = "cc" -version = "1.1.24" +name = "cfg_aliases" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" -dependencies = [ - "jobserver", - "libc", - "shlex", -] +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" [[package]] -name = "cfg-if" -version = "1.0.0" +name = "chacha20" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" +dependencies = [ + "cfg-if", + "cpufeatures", + "rand_core", +] [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "wasm-bindgen", - "windows-targets", + "windows-link", ] [[package]] -name = "cipher" -version = "0.4.4" +name = "cmake" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" dependencies = [ - "crypto-common", - "inout", + "cc", ] [[package]] -name = "constant_time_eq" -version = "0.1.5" +name = "combine" +version = "4.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfc320937d09e6de266b31b9afb480f197d7a861be86be7cb2ea7e5d1bfffc5e" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + +[[package]] +name = "core-foundation" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] [[package]] name = "core-foundation-sys" @@ -185,126 +188,188 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.14" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "8498c871161e1742aaa9d52551b2d6ebdd4c3d45a3be423e3728f33b955be550" dependencies = [ "cfg-if", ] -[[package]] -name = "crossbeam-utils" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" - [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" dependencies = [ - "generic-array", - "typenum", + "hybrid-array", ] [[package]] name = "csv" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +checksum = "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938" dependencies = [ "csv-core", "itoa", "ryu", - "serde", + "serde_core", ] [[package]] name = "csv-core" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782" dependencies = [ "memchr", ] [[package]] -name = "deranged" -version = "0.3.11" +name = "defmt" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" dependencies = [ - "powerfmt", + "bitflags 1.3.2", + "defmt-macros", ] [[package]] -name = "derivative" -version = "2.2.0" +name = "defmt-macros" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" dependencies = [ + "defmt-parser", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.119", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror", +] + +[[package]] +name = "derive_more" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.119", ] [[package]] name = "digest" -version = "0.10.7" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ "block-buffer", + "const-oid", "crypto-common", - "subtle", ] [[package]] -name = "either" -version = "1.13.0" +name = "digest-io" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "2de63d600bc7fab91180bc17385f29b342468dc8ef2af09dceba450a293de3da" +dependencies = [ + "digest", +] [[package]] -name = "flate2" -version = "1.0.34" +name = "displaydoc" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ - "crc32fast", - "miniz_oxide", + "proc-macro2", + "quote", + "syn 3.0.4", ] [[package]] -name = "fnv" -version = "1.0.7" +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "either" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" + +[[package]] +name = "equivalent" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "find-msvc-tools" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" + +[[package]] +name = "flate2" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb" +dependencies = [ + "zlib-rs", +] [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", "futures-sink", @@ -312,33 +377,33 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-core", "futures-io", @@ -346,102 +411,94 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - [[package]] name = "getopts" -version = "0.2.21" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +checksum = "cfe4fbac503b8d1f88e6676011885f34b7174f46e59956bba534ba83abded4df" dependencies = [ "unicode-width", ] [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] -name = "gimli" -version = "0.31.0" +name = "getrandom" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "rand_core", + "wasm-bindgen", +] [[package]] name = "gtfs-structures" -version = "0.41.3" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad38521102d1da04102f3ff28b3f0d8d4b8812cadccc3ff60d858473d9aa3a88" +checksum = "3a0888d9e11d450411608f562a9ad4f75a6464d736167b025576924fc16cdd88" dependencies = [ + "base16ct", "bytes", - "chrono", "csv", - "derivative", + "derive_more", + "digest-io", "itertools", + "jiff", "rgb", "serde", "serde_derive", "sha2", "thiserror", + "web-time", "zip", ] [[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.3.9" +name = "hashbrown" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] -name = "hmac" -version = "0.12.1" +name = "heck" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "http" -version = "1.1.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" dependencies = [ "bytes", - "fnv", "itoa", ] [[package]] name = "http-body" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" dependencies = [ "bytes", "http", @@ -449,12 +506,12 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.2" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" dependencies = [ "bytes", - "futures-util", + "futures-core", "http", "http-body", "pin-project-lite", @@ -462,19 +519,29 @@ dependencies = [ [[package]] name = "httparse" -version = "1.9.5" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hybrid-array" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" +checksum = "707114b52a152fa7bdb290cd7cd5912d9467273b6d74e21b8d81aca1f8533f6b" +dependencies = [ + "typenum", +] [[package]] name = "hyper" -version = "1.4.1" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +checksum = "27b501faa50e7a26c3d3560ca625132f4078a17771f4810baf70475ae48cbe43" dependencies = [ + "atomic-waker", "bytes", "futures-channel", - "futures-util", + "futures-core", "http", "http-body", "httparse", @@ -487,34 +554,35 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.3" +version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ - "futures-util", "http", "hyper", "hyper-util", "rustls", - "rustls-pki-types", "tokio", "tokio-rustls", "tower-service", - "webpki-roots", ] [[package]] name = "hyper-util" -version = "0.1.9" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ + "base64", "bytes", "futures-channel", "futures-util", "http", "http-body", "hyper", + "ipnet", + "libc", + "percent-encoding", "pin-project-lite", "socket2", "tokio", @@ -524,14 +592,15 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.61" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", "windows-core", ] @@ -545,267 +614,405 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" + +[[package]] +name = "icu_properties" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" + +[[package]] +name = "icu_provider" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + [[package]] name = "idna" -version = "0.5.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", ] [[package]] -name = "indoc" -version = "2.0.5" +name = "idna_adapter" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +dependencies = [ + "icu_normalizer", + "icu_properties", +] [[package]] -name = "inout" -version = "0.1.3" +name = "indexmap" +version = "2.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +checksum = "07aa2048142242915a31d35844fb311e0e53fcca590c3a0a40dcf1b841fa09eb" dependencies = [ - "generic-array", + "equivalent", + "hashbrown", ] [[package]] name = "ipnet" -version = "2.10.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" +checksum = "6a756c3fac73139e83f14c2d742155dd2b78d3ee56597b419a0579b7bdd6dd78" [[package]] name = "itertools" -version = "0.11.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] -name = "jobserver" -version = "0.1.32" +name = "jiff" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc" dependencies = [ - "libc", + "defmt", + "jiff-core", + "jiff-static", + "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", + "windows-link", ] [[package]] -name = "js-sys" -version = "0.3.70" +name = "jiff-core" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" dependencies = [ - "wasm-bindgen", + "defmt", ] [[package]] -name = "libc" -version = "0.2.159" +name = "jiff-static" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204" +dependencies = [ + "jiff-core", + "proc-macro2", + "quote", + "syn 2.0.119", +] [[package]] -name = "log" -version = "0.4.22" +name = "jiff-tzdb" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "142bd39932ad231f10513df9ab62661fead8719872150b7ad02a2df79f4e141e" [[package]] -name = "memchr" -version = "2.7.4" +name = "jiff-tzdb-platform" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] [[package]] -name = "memoffset" -version = "0.9.1" +name = "jni" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" dependencies = [ - "autocfg", + "cfg-if", + "combine", + "jni-macros", + "jni-sys", + "log", + "simd_cesu8", + "thiserror", + "walkdir", + "windows-link", ] [[package]] -name = "mime" -version = "0.3.17" +name = "jni-macros" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.119", +] [[package]] -name = "miniz_oxide" -version = "0.8.0" +name = "jni-sys" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" dependencies = [ - "adler2", + "jni-sys-macros", ] [[package]] -name = "mio" -version = "1.0.2" +name = "jni-sys-macros" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" dependencies = [ - "hermit-abi", - "libc", - "wasi", - "windows-sys 0.52.0", + "quote", + "syn 2.0.119", ] [[package]] -name = "num-conv" -version = "0.1.0" +name = "jobserver" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +dependencies = [ + "getrandom 0.4.3", + "libc", +] [[package]] -name = "num-traits" -version = "0.2.19" +name = "js-sys" +version = "0.3.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" dependencies = [ - "autocfg", + "cfg-if", + "futures-util", + "wasm-bindgen", ] [[package]] -name = "object" -version = "0.36.4" +name = "libc" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" -dependencies = [ - "memchr", -] +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] -name = "once_cell" -version = "1.20.1" +name = "litemap" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" -dependencies = [ - "portable-atomic", -] +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" [[package]] -name = "password-hash" -version = "0.4.2" +name = "log" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" + +[[package]] +name = "lru-slab" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "mio" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b18443e9c262bfe8fa82f51666e2642c53393f7e5c27b3e1aeab922cff5b9d8" dependencies = [ - "base64ct", - "rand_core", - "subtle", + "libc", + "wasi", + "windows-sys 0.61.2", ] [[package]] -name = "pbkdf2" -version = "0.11.0" +name = "num-traits" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ - "digest", - "hmac", - "password-hash", - "sha2", + "autocfg", ] [[package]] -name = "percent-encoding" -version = "2.3.1" +name = "once_cell" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] -name = "pin-project-lite" -version = "0.2.14" +name = "openssl-probe" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] -name = "pin-utils" -version = "0.1.0" +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pin-project-lite" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkg-config" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" [[package]] name = "portable-atomic" -version = "1.9.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" [[package]] -name = "powerfmt" -version = "0.2.0" +name = "portable-atomic-util" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +dependencies = [ + "portable-atomic", +] [[package]] -name = "ppv-lite86" -version = "0.2.20" +name = "potential_utf" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" dependencies = [ - "zerocopy", + "zerovec", ] [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] [[package]] name = "pyo3" -version = "0.22.3" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15ee168e30649f7f234c3d49ef5a7a6cbf5134289bc46c29ff3155fa3221c225" +checksum = "4688ddedf473e32662b9b067670129a8afb8c18e351482c70d62ba4a88171e8b" dependencies = [ - "cfg-if", - "indoc", "libc", - "memoffset", "once_cell", "portable-atomic", "pyo3-build-config", "pyo3-ffi", "pyo3-macros", - "unindent", ] [[package]] name = "pyo3-build-config" -version = "0.22.3" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e61cef80755fe9e46bb8a0b8f20752ca7676dcc07a5277d8b7768c6172e529b3" +checksum = "f41027e41b4bd03f6e60f9f417fe24a6341a6bb744edd62b6f709f2a52ea30e9" dependencies = [ - "once_cell", "target-lexicon", ] [[package]] name = "pyo3-ffi" -version = "0.22.3" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ce096073ec5405f5ee2b8b31f03a68e02aa10d5d4f565eca04acc41931fa1c" +checksum = "e591a95526fead067432c3b3a33fc74770b87b1e04e73671090d9c2055a2b327" dependencies = [ "libc", "pyo3-build-config", @@ -813,36 +1020,36 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.22.3" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2440c6d12bc8f3ae39f1e775266fa5122fd0c8891ce7520fa6048e683ad3de28" +checksum = "73225868fc1cd84eef2c3c230ddb91273bf1de46aeb8a4248da76d32a0924a1c" dependencies = [ "proc-macro2", "pyo3-macros-backend", "quote", - "syn 2.0.79", + "syn 2.0.119", ] [[package]] name = "pyo3-macros-backend" -version = "0.22.3" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1be962f0e06da8f8465729ea2cb71a416d2257dff56cbe40a70d3e62a93ae5d1" +checksum = "571575aa3749fa6216757dd47d2a3e7ef360f329a40f0666a9fbd14889024952" dependencies = [ "heck", "proc-macro2", - "pyo3-build-config", "quote", - "syn 2.0.79", + "syn 2.0.119", ] [[package]] name = "quinn" -version = "0.11.5" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" +checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" dependencies = [ "bytes", + "cfg_aliases", "pin-project-lite", "quinn-proto", "quinn-udp", @@ -852,93 +1059,104 @@ dependencies = [ "thiserror", "tokio", "tracing", + "web-time", ] [[package]] name = "quinn-proto" -version = "0.11.8" +version = "0.11.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" +checksum = "04759210543be93709136e28212294a659ef5001836ff4eab4d663e4529bba83" dependencies = [ + "aws-lc-rs", "bytes", + "getrandom 0.4.3", + "lru-slab", "rand", + "rand_pcg", "ring", "rustc-hash", "rustls", + "rustls-pki-types", "slab", "thiserror", "tinyvec", "tracing", + "web-time", ] [[package]] name = "quinn-udp" -version = "0.5.5" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fe68c2e9e1a1234e218683dbdf9f9dfcb094113c5ac2b938dfcb9bab4c4140b" +checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694" dependencies = [ + "cfg_aliases", "libc", "once_cell", "socket2", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "quote" -version = "1.0.37" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] [[package]] -name = "rand" -version = "0.8.5" +name = "r-efi" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] -name = "rand_chacha" -version = "0.3.1" +name = "rand" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ - "ppv-lite86", + "chacha20", + "getrandom 0.4.3", "rand_core", ] [[package]] name = "rand_core" -version = "0.6.4" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + +[[package]] +name = "rand_pcg" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" dependencies = [ - "getrandom", + "rand_core", ] [[package]] name = "renfe-cli" -version = "5.2.0" +version = "6.0.0" dependencies = [ "chrono", "getopts", "gtfs-structures", + "jiff", "pyo3", "reqwest", ] [[package]] name = "reqwest" -version = "0.12.8" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" +checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" dependencies = [ "base64", "bytes", @@ -951,76 +1169,72 @@ dependencies = [ "hyper", "hyper-rustls", "hyper-util", - "ipnet", "js-sys", "log", - "mime", - "once_cell", "percent-encoding", "pin-project-lite", "quinn", "rustls", - "rustls-pemfile", "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", + "rustls-platform-verifier", "sync_wrapper", "tokio", "tokio-rustls", + "tower", + "tower-http", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", - "windows-registry", ] [[package]] name = "rgb" -version = "0.8.50" +version = "0.8.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" +checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4" dependencies = [ "bytemuck", ] [[package]] name = "ring" -version = "0.17.8" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom", + "getrandom 0.2.17", "libc", - "spin", "untrusted", "windows-sys 0.52.0", ] [[package]] -name = "rustc-demangle" -version = "0.1.24" +name = "rustc-hash" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] -name = "rustc-hash" -version = "2.0.0" +name = "rustc_version" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] [[package]] name = "rustls" -version = "0.23.13" +version = "0.23.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" +checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" dependencies = [ + "aws-lc-rs", "once_cell", - "ring", "rustls-pki-types", "rustls-webpki", "subtle", @@ -1028,97 +1242,159 @@ dependencies = [ ] [[package]] -name = "rustls-pemfile" -version = "2.2.0" +name = "rustls-native-certs" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" dependencies = [ + "openssl-probe", "rustls-pki-types", + "schannel", + "security-framework", ] [[package]] name = "rustls-pki-types" -version = "1.9.0" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-platform-verifier" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" +dependencies = [ + "core-foundation", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.102.8" +version = "0.103.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", ] +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] -name = "serde" -version = "1.0.210" +name = "same-file" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ - "serde_derive", + "winapi-util", ] [[package]] -name = "serde_derive" -version = "1.0.210" +name = "schannel" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", + "windows-sys 0.61.2", ] [[package]] -name = "serde_json" -version = "1.0.128" +name = "security-framework" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", + "bitflags 2.13.1", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", ] [[package]] -name = "serde_urlencoded" -version = "0.7.1" +name = "security-framework-sys" +version = "2.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", ] [[package]] -name = "sha1" -version = "0.10.6" +name = "serde_core" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ - "cfg-if", - "cpufeatures", - "digest", + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.4", ] [[package]] name = "sha2" -version = "0.10.8" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ "cfg-if", "cpufeatures", @@ -1127,40 +1403,59 @@ dependencies = [ [[package]] name = "shlex" -version = "1.3.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] -name = "slab" -version = "0.4.9" +name = "simd-adler32" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" + +[[package]] +name = "simd_cesu8" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" dependencies = [ - "autocfg", + "rustc_version", + "simdutf8", ] +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + [[package]] name = "smallvec" -version = "1.13.2" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "b9be42f50aa861c555654aa3a37f52f4b1074bacf4e48fe0ef7fa584e80f1f0f" [[package]] name = "socket2" -version = "0.5.7" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] -name = "spin" -version = "0.9.8" +name = "stable_deref_trait" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "subtle" @@ -1170,9 +1465,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" dependencies = [ "proc-macro2", "quote", @@ -1181,9 +1476,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "e6275cddf4610d1775e6d1fe9469b2e77d0f39fd98fb7450901b821e0c53649f" dependencies = [ "proc-macro2", "quote", @@ -1192,63 +1487,65 @@ dependencies = [ [[package]] name = "sync_wrapper" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" dependencies = [ "futures-core", ] +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "target-lexicon" -version = "0.12.16" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" [[package]] name = "thiserror" -version = "1.0.64" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 3.0.4", ] [[package]] -name = "time" -version = "0.3.36" +name = "tinystr" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" dependencies = [ - "deranged", - "num-conv", - "powerfmt", - "serde", - "time-core", + "displaydoc", + "zerovec", ] -[[package]] -name = "time-core" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" - [[package]] name = "tinyvec" -version = "1.8.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" dependencies = [ "tinyvec_macros", ] @@ -1261,30 +1558,67 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.40.0" +version = "1.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" dependencies = [ - "backtrace", "bytes", "libc", "mio", "pin-project-lite", "socket2", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] name = "tokio-rustls" -version = "0.26.0" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ "rustls", - "rustls-pki-types", "tokio", ] +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" +dependencies = [ + "bitflags 2.13.1", + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", + "url", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + [[package]] name = "tower-service" version = "0.3.3" @@ -1293,9 +1627,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "pin-project-lite", "tracing-core", @@ -1303,9 +1637,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", ] @@ -1317,43 +1651,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] -name = "typenum" -version = "1.17.0" +name = "typed-path" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "8e28f89b80c87b8fb0cf04ab448d5dd0dd0ade2f8891bae878de66a75a28600e" [[package]] -name = "unicode-bidi" -version = "0.3.15" +name = "typenum" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "unicode-ident" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" - -[[package]] -name = "unicode-normalization" -version = "0.1.24" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" -dependencies = [ - "tinyvec", -] +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-width" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" - -[[package]] -name = "unindent" -version = "0.2.3" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "untrusted" @@ -1363,20 +1682,31 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.2" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] -name = "version_check" -version = "0.9.5" +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "walkdir" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] [[package]] name = "want" @@ -1389,53 +1719,38 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.79", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.43" +version = "0.4.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +checksum = "6b7777d5cc23d0e91404e53ce2d5e8ec7acae3026b16233dba62cd3246457950" dependencies = [ - "cfg-if", "js-sys", "wasm-bindgen", - "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1443,79 +1758,121 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284" dependencies = [ + "bumpalo", "proc-macro2", "quote", - "syn 2.0.79", - "wasm-bindgen-backend", + "syn 2.0.119", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf" +dependencies = [ + "unicode-ident", +] [[package]] name = "web-sys" -version = "0.3.70" +version = "0.3.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c435338968042f4f59a557f690a253676d47ce13ceb55d70100e7facf6620a30" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", ] [[package]] -name = "webpki-roots" -version = "0.26.6" +name = "webpki-root-certs" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b" dependencies = [ "rustls-pki-types", ] [[package]] -name = "windows-core" -version = "0.52.0" +name = "winapi-util" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-targets", + "windows-sys 0.61.2", ] [[package]] -name = "windows-registry" -version = "0.2.0" +name = "windows-core" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", "windows-result", "windows-strings", - "windows-targets", ] +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-result" -version = "0.2.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-targets", + "windows-link", ] [[package]] name = "windows-strings" -version = "0.1.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-result", - "windows-targets", + "windows-link", ] [[package]] @@ -1529,11 +1886,11 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.59.0" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-targets", + "windows-link", ] [[package]] @@ -1601,77 +1958,122 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "zerocopy" -version = "0.7.35" +name = "writeable" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" + +[[package]] +name = "yoke" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "synstructure", +] + +[[package]] +name = "zerofrom" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ - "byteorder", - "zerocopy-derive", + "zerofrom-derive", ] [[package]] -name = "zerocopy-derive" -version = "0.7.35" +name = "zerofrom-derive" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.119", + "synstructure", ] [[package]] name = "zeroize" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" [[package]] -name = "zip" -version = "0.6.6" +name = "zerotrie" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" dependencies = [ - "aes", - "byteorder", - "bzip2", - "constant_time_eq", - "crc32fast", - "crossbeam-utils", - "flate2", - "hmac", - "pbkdf2", - "sha1", - "time", - "zstd", + "displaydoc", + "yoke", + "zerofrom", ] [[package]] -name = "zstd" -version = "0.11.2+zstd.1.5.2" +name = "zerovec" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" dependencies = [ - "zstd-safe", + "yoke", + "zerofrom", + "zerovec-derive", ] [[package]] -name = "zstd-safe" -version = "5.0.2+zstd.1.5.2" +name = "zerovec-derive" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" dependencies = [ - "libc", - "zstd-sys", + "proc-macro2", + "quote", + "syn 3.0.4", +] + +[[package]] +name = "zip" +version = "8.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d04a6b5381502aa6087c94c669499eb1602eb9c5e8198e534de571f7154809b" +dependencies = [ + "crc32fast", + "flate2", + "indexmap", + "memchr", + "typed-path", + "zopfli", ] [[package]] -name = "zstd-sys" -version = "2.0.13+zstd.1.5.6" +name = "zlib-rs" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" +checksum = "34b31d188d9d685a4f9c7b46d6e36631b07058d2cfe190267adce54dc230bf12" + +[[package]] +name = "zopfli" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249" dependencies = [ - "cc", - "pkg-config", + "bumpalo", + "crc32fast", + "log", + "simd-adler32", ] diff --git a/Cargo.toml b/Cargo.toml index a1a015a..2cc9907 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,8 @@ [package] name = "renfe-cli" -version = "5.2.0" -edition = "2021" +version = "6.0.0" +edition = "2024" +rust-version = "1.98" authors = ["Gerard C.L. "] license = "BSD-3-Clause" description = "CLI for searching Renfe train timetables in the Spanish country" @@ -18,8 +19,9 @@ name = "renfe_cli" crate-type = ["cdylib", "lib"] [dependencies] -pyo3 = { version = "0.22", features = ["abi3-py37"] } -getopts = "0.2" -chrono = "0.4" -gtfs-structures = { version = "0.41", default-features = false } -reqwest = { version = "0.12", default-features = false, features = ["blocking", "rustls-tls"] } +pyo3 = { version = "0.29", features = ["abi3-py310"] } +getopts = "0.2.24" +chrono = "0.4.45" +gtfs-structures = { version = "0.50", default-features = false } +jiff = "0.2.35" +reqwest = { version = "0.13", default-features = false, features = ["blocking", "rustls"] } diff --git a/README.md b/README.md index 7107b05..d86c066 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@ # Renfe Timetables CLI -Get faster Renfe trains timetables in your terminal, with Python3.8+ support. +Get faster Renfe trains timetables in your terminal, with Python 3.10+ support. No longer need to open the browser! Just keep using your terminal πŸ˜€ -It supports both [Horarios de alta velocidad, larga distancia y media distancia](https://data.renfe.com/dataset/horarios-de-alta-velocidad-larga-distancia-y-media-distancia) (default option, as in the web) and [Renfe CercanΓ­as](https://data.renfe.com/dataset/horarios-cercanias) GTFS datasets. +It supports both [Horarios de alta velocidad, larga distancia y media distancia](https://data.renfe.com/dataset/horarios-de-alta-velocidad-larga-distancia-y-media-distancia) (default option, as in the web) and [Renfe CercanΓ­as](https://data.renfe.com/dataset/horarios-cercanias) GTFS datasets. Timetable searches include connections with up to three transfers. The router favors shorter journeys and applies a transfer penalty so a marginal time saving does not produce an unnecessarily complicated itinerary. `renfe-cli` is written in [Rust](https://www.rust-lang.org/) (since v4.0.0) and published to [pypi.org](https://pypi.org/project/renfe-cli/) as a Python package (CLI and library). @@ -24,7 +24,7 @@ See the [changelog](https://github.com/gerardcl/renfe-cli/blob/master/CHANGELOG. Install Python CLI package [renfe-cli](https://pypi.org/project/renfe-cli/) ```bash -pip install renfe-cli --upgrade +uv tool install renfe-cli --upgrade ``` ### Rust crate (optional) @@ -182,26 +182,17 @@ If Renfe's GTFS dataset is being kept not up to date or you find any issue to be ### Development -This project makes use of Rust bindings for the Python interpreter thanks to [pyo3](https://pyo3.rs). It is already available as a dependency. +This project uses Rust bindings for the Python interpreter through [PyO3](https://pyo3.rs) and [Maturin](https://www.maturin.rs/) to build and install the Python package. -To develop, build and publish, this project makes use of [maturin](https://www.maturin.rs/) project. See [usage](https://www.maturin.rs/#usage). - -Example of first time working with this repository: +Install [uv](https://docs.astral.sh/uv/getting-started/installation/) first, then set up a development environment: ```bash -$ git clone https://github.com/gerardcl/renfe-cli.git && cd renfe-cli -$ python -m venv .venv -$ . .venv/bin/activate -$ pip install -U pip -$ pip install -U maturin -$ maturin develop -πŸ”— Found pyo3 bindings with abi3 support for Python β‰₯ 3.7 -🐍 Not using a specific python interpreter -πŸ“‘ Using build options features from pyproject.toml - Compiling renfe-cli v5.1.0 (/path/to/renfe-cli) - Finished dev [unoptimized + debuginfo] target(s) in 7.07s -πŸ“¦ Built wheel for abi3 Python β‰₯ 3.7 to /tmp/.tmpDsjowL/renfe_cli-5.1.0-cp37-abi3-linux_x86_64.whl -πŸ›  Installed renfe-cli-5.1.0 +git clone https://github.com/gerardcl/renfe-cli.git +cd renfe-cli +uv python install 3.10 +uv venv --python 3.10 +source .venv/bin/activate +uvx maturin develop --uv ``` -Maturin takes care of compiling the rust code, generating the bindings for python and installing the package for local use (as library or binary/CLI). +Maturin compiles the Rust code, generates the Python bindings, and installs the package into `.venv` for local use as a library or CLI. After changing Rust code, run `uvx maturin develop --uv` again to rebuild it. Use `uv run renfe-cli --help` to run the development installation. diff --git a/pyproject.toml b/pyproject.toml index 3a4c383..dec1425 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,10 @@ [build-system] -requires = ["maturin>=1.3,<2.0"] +requires = ["maturin>=1.15,<2.0"] build-backend = "maturin" [project] name = "renfe-cli" -requires-python = ">=3.8" +requires-python = ">=3.10" authors = [ {name = "Gerard Castillo Lasheras", email = "gerardcl@gmail.com"}, ] @@ -17,6 +17,11 @@ license = {file = "LICENSE"} keywords = ["timetables", "schedules", "trains", "renfe", "cli", "rust", "python", "pyo3", "maturin"] classifiers = [ "Programming Language :: Rust", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Development Status :: 4 - Beta", diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..8f13c69 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,7 @@ +[toolchain] +channel = "1.98.0" +# https://rust-lang.github.io/rustup/concepts/profiles.html +profile = "default" +# Pins the rust-analyzer LSP server to this toolchain so editors (VS Code, Zed, etc.) +# use the same Rust version for analysis and clippy β€” not the system default. +components = ["rustfmt", "clippy", "rust-analyzer"] diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..f9a34f4 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,24 @@ +# https://github.com/rust-lang/rustfmt/blob/master/Configurations.md +# ───────────────────────────────────────────── +# πŸ“¦ Edition +edition = "2024" +# ───────────────────────────────────────────── +# πŸ“š Import organization +# group_imports = "StdExternalCrate" # Group: std, external crates, then local +# imports_granularity = "Module" # One use per module line (avoids merge conflicts) +reorder_imports = true # Ensure deterministic ordering +# ───────────────────────────────────────────── +# πŸ“ Formatting rules +use_field_init_shorthand = true # Use shorthand: { foo } instead of { foo: foo } +match_block_trailing_comma = true # Add trailing commas in multiline match arms +# trailing_comma = "Always" # Always use trailing commas in multiline +newline_style = "Unix" # Use \n (LF) for line endings +tab_spaces = 2 # Use 2 spaces per indentation level +max_width = 100 # Line length limit +# ───────────────────────────────────────────── +# 🧼 Style preferences +# normalize_doc_attributes = true # Normalize #[doc] to /// comments +# wrap_comments = true # Automatically wrap long doc/comments +# format_code_in_doc_comments = true # Format Rust code inside doc comments +# blank_lines_upper_bound = 1 # Avoid excessive vertical whitespace +# blank_lines_lower_bound = 0 # Allow compact block spacing when possible diff --git a/src/cli.rs b/src/cli.rs index 63c5c36..0b4dfc0 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,81 +1,81 @@ use chrono::{Datelike, Utc}; use getopts::Options; -use pyo3::{exceptions::PyValueError, pyfunction, PyResult}; +use pyo3::{PyResult, exceptions::PyValueError, pyfunction}; use std::env; use crate::renfe::Renfe; #[pyfunction] pub fn main() -> PyResult<()> { - let args: Vec = env::args().collect(); - let program = args[0].clone(); - let now = Utc::now(); - let opts = set_opts(); + let args: Vec = env::args().collect(); + let program = args[0].clone(); + let now = Utc::now(); + let opts = set_opts(); - let matches = match opts.parse(&args[1..]) { - Ok(m) => m, - Err(f) => { - return Err(PyValueError::new_err(f.to_string())); - } - }; + let matches = match opts.parse(&args[1..]) { + Ok(m) => m, + Err(f) => { + return Err(PyValueError::new_err(f.to_string())); + }, + }; - if matches.opt_present("h") { - print_usage(&program, opts); - return Ok(()); - } + if matches.opt_present("h") { + print_usage(&program, opts); + return Ok(()); + } - let mut renfe = Renfe::new(matches.opt_present("c"))?; + let mut renfe = Renfe::new(matches.opt_present("c"))?; - let origin = renfe.filter_station(matches.opt_str("f").expect("Missing origin station"))?; - let destination = - renfe.filter_station(matches.opt_str("t").expect("Missing destination station"))?; - let day = match matches.opt_str("d") { - Some(day) => day.parse()?, - None => now.day(), - }; - let month = match matches.opt_str("m") { - Some(day) => day.parse()?, - None => now.month(), - }; - let year = match matches.opt_str("y") { - Some(day) => day.parse()?, - None => now.year(), - }; - let sorted: bool = matches.opt_present("s"); + let origin = renfe.filter_station(matches.opt_str("f").expect("Missing origin station"))?; + let destination = + renfe.filter_station(matches.opt_str("t").expect("Missing destination station"))?; + let day = match matches.opt_str("d") { + Some(day) => day.parse()?, + None => now.day(), + }; + let month = match matches.opt_str("m") { + Some(day) => day.parse()?, + None => now.month(), + }; + let year = match matches.opt_str("y") { + Some(day) => day.parse()?, + None => now.year(), + }; + let sorted: bool = matches.opt_present("s"); - println!("Today is: {}-{}-{}", now.year(), now.month(), now.day()); - println!("Searching timetable for date: {}-{}-{}", year, month, day); + println!("Today is: {}-{}-{}", now.year(), now.month(), now.day()); + println!("Searching timetable for date: {}-{}-{}", year, month, day); - renfe.set_train_schedules(&origin.id, &destination.id, day, month, year, sorted)?; + renfe.set_train_schedules(&origin.id, &destination.id, day, month, year, sorted)?; - println!("Origin station: {}", origin.name); - println!("Destination station: {}", destination.name); + println!("Origin station: {}", origin.name); + println!("Destination station: {}", destination.name); - renfe.print_timetable(); + renfe.print_timetable(); - Ok(()) + Ok(()) } fn print_usage(program: &str, opts: Options) { - let brief = format!("Usage: {} [options]", program); - print!("{}", opts.usage(&brief)); + let brief = format!("Usage: {} [options]", program); + print!("{}", opts.usage(&brief)); } fn set_opts() -> Options { - let mut opts = Options::new(); - opts.optopt("f", "", "Set From origin station", "ORIGIN"); - opts.optopt("t", "", "Set To destination station", "DESTINATION"); - opts.optopt("d", "day", "Set the Day (default: today's day)", "DAY"); - opts.optopt( - "m", - "month", - "Set the Month (default: today's month)", - "MONTH", - ); - opts.optopt("y", "year", "Set the Year (default: today's year)", "YEAR"); - opts.optflag("s", "sort", "Option to sort the timetable by Duration"); - opts.optflag("c", "cercanias", "Option to search over Renfe CercanΓ­as"); - opts.optflag("h", "help", "Print this help menu"); + let mut opts = Options::new(); + opts.optopt("f", "", "Set From origin station", "ORIGIN"); + opts.optopt("t", "", "Set To destination station", "DESTINATION"); + opts.optopt("d", "day", "Set the Day (default: today's day)", "DAY"); + opts.optopt( + "m", + "month", + "Set the Month (default: today's month)", + "MONTH", + ); + opts.optopt("y", "year", "Set the Year (default: today's year)", "YEAR"); + opts.optflag("s", "sort", "Option to sort the timetable by Duration"); + opts.optflag("c", "cercanias", "Option to search over Renfe CercanΓ­as"); + opts.optflag("h", "help", "Print this help menu"); - opts + opts } diff --git a/src/lib.rs b/src/lib.rs index 0eba183..5425d9c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ pub mod cli; pub mod renfe; +mod router; use pyo3::prelude::*; @@ -11,10 +12,10 @@ use renfe::{Renfe, Schedule, Station}; /// import the module. #[pymodule] fn renfe_cli(m: &Bound<'_, PyModule>) -> PyResult<()> { - m.add_class::()?; - m.add_class::()?; - m.add_class::()?; - m.add_function(wrap_pyfunction!(main, m)?)?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_function(wrap_pyfunction!(main, m)?)?; - Ok(()) + Ok(()) } diff --git a/src/main.rs b/src/main.rs index a7d9305..8498821 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,10 @@ use renfe_cli::cli; fn main() -> Result<(), pyo3::PyErr> { - // Initialize the Python interpreter required - pyo3::prepare_freethreaded_python(); + // Initialize the Python interpreter required + pyo3::Python::initialize(); - cli::main()?; + cli::main()?; - Ok(()) + Ok(()) } diff --git a/src/renfe.rs b/src/renfe.rs index 2627076..595dde1 100644 --- a/src/renfe.rs +++ b/src/renfe.rs @@ -1,38 +1,41 @@ -use chrono::{Datelike, NaiveDate, NaiveTime, TimeDelta, Timelike}; -use gtfs_structures::Gtfs; -use pyo3::{exceptions::PyValueError, pyclass, pymethods, PyResult}; +use chrono::{NaiveTime, TimeDelta, Timelike}; +use gtfs_structures::{Gtfs, TransferType}; +use jiff::civil::{Date, Weekday}; +use pyo3::{PyResult, exceptions::PyValueError, pyclass, pymethods}; use std::io::Read; +use crate::router::{StopTime, Transfer, Trip, find_journeys}; + #[pyclass] pub struct Renfe { - gtfs: Gtfs, - schedules: Vec, + gtfs: Gtfs, + schedules: Vec, } // Struct to hold the schedule details #[pyclass] pub struct Schedule { - train_type: String, - // origin_stop_name: String, - // destination_stop_name: String, - departure_time: NaiveTime, - arrival_time: NaiveTime, - duration: TimeDelta, + train_type: String, + service_departure: u32, + departure_time: NaiveTime, + arrival_time: NaiveTime, + duration: TimeDelta, + transfers: usize, } // Struct to hold the station name and ID -#[pyclass] +#[pyclass(skip_from_py_object)] #[derive(Debug, Clone)] pub struct Station { - pub name: String, - pub id: String, + pub name: String, + pub id: String, } #[pymethods] impl Renfe { - #[new] - pub fn new(cercanias: bool) -> PyResult { - let mut res = reqwest::blocking::get( + #[new] + pub fn new(cercanias: bool) -> PyResult { + let mut res = reqwest::blocking::get( match cercanias { false => { println!("Loading default GTFS data from Renfe web - Alta velocidad, Larga distancia y Media distancia"); @@ -45,234 +48,252 @@ impl Renfe { }, ) .expect("Error downloading GTFS zip file"); - let mut body = Vec::new(); - res.read_to_end(&mut body)?; - let cursor = std::io::Cursor::new(body); + let mut body = Vec::new(); + res.read_to_end(&mut body)?; + let cursor = std::io::Cursor::new(body); - let gtfs = Gtfs::from_reader(cursor).expect("Error parsing GTFS zip"); + let gtfs = Gtfs::from_reader(cursor).expect("Error parsing GTFS zip"); - gtfs.print_stats(); + gtfs.print_stats(); - Ok(Renfe { - gtfs, - schedules: Vec::new(), - }) - } + Ok(Renfe { + gtfs, + schedules: Vec::new(), + }) + } - pub fn all_stations(&self) -> PyResult> { - let stations: Vec = self - .gtfs - .stops - .iter() - .map(|s| Station { - name: s.1.name.clone().unwrap(), - id: s.1.id.clone(), - }) - .collect(); - Ok(stations) - } + pub fn all_stations(&self) -> PyResult> { + let stations: Vec = self + .gtfs + .stops + .iter() + .map(|s| Station { + name: s.1.name.clone().unwrap(), + id: s.1.id.clone(), + }) + .collect(); + Ok(stations) + } - pub fn stations_match(&self, station: String) -> PyResult> { - let found: Vec = self - .gtfs - .stops - .iter() - .filter(|s| { - s.1.name - .clone() - .unwrap() - .to_lowercase() - .contains(&station.to_lowercase()) - }) - .map(|s| Station { - name: s.1.name.clone().unwrap(), - id: s.1.id.clone(), - }) - .collect(); - Ok(found) - } + pub fn stations_match(&self, station: String) -> PyResult> { + let found: Vec = self + .gtfs + .stops + .iter() + .filter(|s| { + s.1 + .name + .clone() + .unwrap() + .to_lowercase() + .contains(&station.to_lowercase()) + }) + .map(|s| Station { + name: s.1.name.clone().unwrap(), + id: s.1.id.clone(), + }) + .collect(); + Ok(found) + } - pub fn filter_station(&self, station: String) -> PyResult { - match self.stations_match(station.clone()) { - Ok(v) if v.len() == 1 => { - println!( - "Provided input '{}' does a match with '{:?}'", - station, v[0] - ); - Ok(v[0].clone()) - } - Ok(v) => Err(PyValueError::new_err(format!( - "Provided input '{station}' does match with '{v:?}' -> There must be ONLY one match" - ))), - Err(e) => Err(e), - } + pub fn filter_station(&self, station: String) -> PyResult { + match self.stations_match(station.clone()) { + Ok(v) if v.len() == 1 => { + println!( + "Provided input '{}' does a match with '{:?}'", + station, v[0] + ); + Ok(v[0].clone()) + }, + Ok(v) => Err(PyValueError::new_err(format!( + "Provided input '{station}' does match with '{v:?}' -> There must be ONLY one match" + ))), + Err(e) => Err(e), } + } - // Function to get train schedules between an origin and a destination on a given date - pub fn set_train_schedules( - &mut self, - origin_station_id: &str, - destination_station_id: &str, - day: u32, - month: u32, - year: i32, - sorted: bool, - ) -> PyResult<()> { - let gtfs = &self.gtfs; - // the date for which schedules are needed - let date = match NaiveDate::from_ymd_opt(year, month, day) { - Some(date) => date, - None => { - return Err(PyValueError::new_err(format!( - "Provided date '{year}-{month}-{day}' does not exist" - ))) - } - }; - - let mut schedules = Vec::new(); - - // Loop through each trip to find ones active on the given date - for trip in gtfs.trips.values() { - // Check if the trip's service is active on the given date - if is_service_active(gtfs, &trip.service_id, date) { - // Filter stop times for the trip - let stop_times: Vec<_> = trip.stop_times.clone(); - - // Find the origin and destination stops in the trip's stop times - let origin_stop = stop_times.iter().find(|st| st.stop.id == origin_station_id); - let destination_stop = stop_times - .iter() - .find(|st| st.stop.id == destination_station_id); + // Function to get train schedules between an origin and a destination on a given date + pub fn set_train_schedules( + &mut self, + origin_station_id: &str, + destination_station_id: &str, + day: u32, + month: u32, + year: i32, + sorted: bool, + ) -> PyResult<()> { + let gtfs = &self.gtfs; + // the date for which schedules are needed + let date = i16::try_from(year) + .ok() + .zip(i8::try_from(month).ok()) + .zip(i8::try_from(day).ok()) + .and_then(|((year, month), day)| Date::new(year, month, day).ok()); + let date = match date { + Some(date) => date, + None => { + return Err(PyValueError::new_err(format!( + "Provided date '{year}-{month}-{day}' does not exist" + ))); + }, + }; - // If the trip includes both origin and destination, and origin is before destination - if let (Some(origin), Some(destination)) = (origin_stop, destination_stop) { - if origin.stop_sequence < destination.stop_sequence { - let time_origin = origin.departure_time.unwrap(); - let time_destination = destination.arrival_time.unwrap(); - let departure_time = NaiveTime::from_hms_opt( - (time_origin / 3600) % 24, - time_origin % 3600 / 60, - time_origin % 60, - ) - .unwrap(); - let arrival_time = NaiveTime::from_hms_opt( - (time_destination / 3600) % 24, - time_destination % 3600 / 60, - time_destination % 60, - ) - .unwrap(); + let trips: Vec<_> = gtfs + .trips + .values() + .filter(|trip| is_service_active(gtfs, &trip.service_id, date)) + .filter_map(|trip| { + let stop_times: Vec<_> = trip + .stop_times + .iter() + .filter_map(|stop_time| { + Some(StopTime { + stop_id: stop_time.stop.id.clone(), + arrival: stop_time.arrival_time?, + departure: stop_time.departure_time?, + }) + }) + .collect(); + (stop_times.len() >= 2).then(|| Trip { + id: trip.id.clone(), + name: gtfs + .get_route(&trip.route_id) + .ok() + .and_then(|route| route.short_name.clone().or_else(|| route.long_name.clone())) + .or_else(|| trip.trip_short_name.clone()) + .unwrap_or_else(|| trip.route_id.clone()), + stop_times, + }) + }) + .collect(); + let transfers: Vec<_> = gtfs + .stops + .values() + .flat_map(|stop| { + stop.transfers.iter().map(|transfer| Transfer { + from_stop_id: stop.id.clone(), + to_stop_id: transfer.to_stop_id.clone(), + duration: (transfer.transfer_type != TransferType::Impossible) + .then(|| transfer.min_transfer_time.unwrap_or(5 * 60)), + }) + }) + .collect(); - let mut duration = arrival_time.signed_duration_since(departure_time); - if time_destination >= 86400 { - duration = duration.checked_add(&TimeDelta::seconds(86400)).unwrap(); - } + let mut schedules: Vec<_> = find_journeys( + &trips, + &transfers, + origin_station_id, + destination_station_id, + ) + .into_iter() + .filter_map(|journey| { + let departure = journey.departure(); + let arrival = journey.arrival(); + Some(Schedule { + train_type: journey + .legs + .iter() + .map(|leg| leg.name.as_str()) + .collect::>() + .join(" β†’ "), + service_departure: departure, + departure_time: seconds_to_time(departure)?, + arrival_time: seconds_to_time(arrival)?, + duration: TimeDelta::seconds(i64::from(arrival.saturating_sub(departure))), + transfers: journey.transfers(), + }) + }) + .collect(); - schedules.push(Schedule { - train_type: gtfs - .get_route(&trip.route_id) - .unwrap() - .short_name - .clone() - .unwrap(), - // origin_stop_name: gtfs.stops[&origin.stop.id].name.clone().unwrap(), - // destination_stop_name: gtfs.stops[&destination.stop.id] - // .name - // .clone() - // .unwrap(), - departure_time, - arrival_time, - duration, - }); - } - } - } - } + // Sort schedules by departure_time + schedules.sort_by_key(|schedule| schedule.service_departure); - // Sort schedules by departure_time - schedules.sort_by_key(|schedule| schedule.departure_time); + if sorted { + println!("sorting timetable by duration"); + schedules.sort_by_key(|schedule| schedule.duration); + } - if sorted { - println!("sorting timetable by duration"); - schedules.sort_by(|a, b| a.duration.cmp(&b.duration)); - } + self.schedules = schedules; - self.schedules = schedules; + Ok(()) + } - Ok(()) + pub fn print_timetable(&self) { + if self.schedules.is_empty() { + println!("\nNo schedules available...won't print timetable."); + } else { + println!("\n================================TIMETABLE================================"); + println!( + " {0: <22} | {1: <9} | {2: <7} | {3: <8} | {4: <9}", + "Trains", "Departure", "Arrival", "Duration", "Transfers" + ); + for track in &self.schedules { + println!("-------------------------------------------------------------------------"); + println!( + " {0: <22} | {1: <7} | {2: <7} | {3: <7} | {4: <4}", + track.train_type, + format!( + "{:02}:{:02}", + track.departure_time.hour(), + track.departure_time.minute() % 60 + ), + format!( + "{:02}:{:02}", + track.arrival_time.hour(), + track.arrival_time.minute() % 60 + ), + format!( + "{:02}:{:02}", + track.duration.num_hours(), + track.duration.num_minutes() % 60 + ), + track.transfers + ); + } + println!("========================================================================="); } + } +} - pub fn print_timetable(&self) { - if self.schedules.is_empty() { - println!("\nNo schedules available...won't print timetable."); - } else { - println!("\n=========================TIMETABLE========================="); - println!( - " {0: <12} | {1: <10} | {2: <10} | {3: <12}", - "Train", "Departure", "Arrival", "Duration" - ); - for track in &self.schedules { - println!("-----------------------------------------------------------"); - println!( - " {0: <11} | {1: <9} | {2: <9} | {3: <10}", - track.train_type, - format!( - "{:02}:{:02}", - track.departure_time.hour(), - track.departure_time.minute() % 60 - ), - format!( - "{:02}:{:02}", - track.arrival_time.hour(), - track.arrival_time.minute() % 60 - ), - format!( - "{:02}:{:02}", - track.duration.num_hours(), - track.duration.num_minutes() % 60 - ) - ); - } - println!("==========================================================="); - } - } +fn seconds_to_time(seconds: u32) -> Option { + NaiveTime::from_hms_opt((seconds / 3600) % 24, seconds % 3600 / 60, seconds % 60) } // Helper function to check if a service is active on a given date -fn is_service_active(gtfs: &Gtfs, service_id: &str, date: NaiveDate) -> bool { - // First check the `calendar.txt` - if let Some(calendar) = gtfs.calendar.get(service_id) { - let weekday = match date.weekday() { - chrono::Weekday::Mon => calendar.monday, - chrono::Weekday::Tue => calendar.tuesday, - chrono::Weekday::Wed => calendar.wednesday, - chrono::Weekday::Thu => calendar.thursday, - chrono::Weekday::Fri => calendar.friday, - chrono::Weekday::Sat => calendar.saturday, - chrono::Weekday::Sun => calendar.sunday, - }; +fn is_service_active(gtfs: &Gtfs, service_id: &str, date: Date) -> bool { + // First check the `calendar.txt` + if let Some(calendar) = gtfs.calendar.get(service_id) { + let weekday = match date.weekday() { + Weekday::Monday => calendar.monday, + Weekday::Tuesday => calendar.tuesday, + Weekday::Wednesday => calendar.wednesday, + Weekday::Thursday => calendar.thursday, + Weekday::Friday => calendar.friday, + Weekday::Saturday => calendar.saturday, + Weekday::Sunday => calendar.sunday, + }; - if weekday && date >= calendar.start_date && date <= calendar.end_date { - // this should never happen - but a check is for free - if let Some(calendar_dates) = gtfs.calendar_dates.get(service_id) { - for date_override in calendar_dates { - if date_override.date == date { - return !(date_override.exception_type - == gtfs_structures::Exception::Deleted); - } - } - } - return true; + if weekday && date >= calendar.start_date && date <= calendar.end_date { + // this should never happen - but a check is for free + if let Some(calendar_dates) = gtfs.calendar_dates.get(service_id) { + for date_override in calendar_dates { + if date_override.date == date { + return !(date_override.exception_type == gtfs_structures::Exception::Deleted); + } } + } + return true; } + } - // Then check the `calendar_dates.txt` for exceptions - if let Some(calendar_dates) = gtfs.calendar_dates.get(service_id) { - for date_override in calendar_dates { - if date_override.date == date { - return date_override.exception_type == gtfs_structures::Exception::Added; - } - } + // Then check the `calendar_dates.txt` for exceptions + if let Some(calendar_dates) = gtfs.calendar_dates.get(service_id) { + for date_override in calendar_dates { + if date_override.date == date { + return date_override.exception_type == gtfs_structures::Exception::Added; + } } + } - false + false } diff --git a/src/router.rs b/src/router.rs new file mode 100644 index 0000000..a51e758 --- /dev/null +++ b/src/router.rs @@ -0,0 +1,351 @@ +use std::collections::{HashMap, HashSet}; + +pub const MAX_TRANSFERS: usize = 3; +const MAX_LEGS: usize = MAX_TRANSFERS + 1; +const DEFAULT_TRANSFER_TIME: u32 = 5 * 60; +const TRANSFER_PENALTY: u32 = 15 * 60; +const MAX_JOURNEY_TIME: u32 = 24 * 60 * 60; + +#[derive(Clone, Debug)] +pub struct StopTime { + pub stop_id: String, + pub arrival: u32, + pub departure: u32, +} + +#[derive(Clone, Debug)] +pub struct Trip { + pub id: String, + pub name: String, + pub stop_times: Vec, +} + +#[derive(Clone, Debug)] +pub struct Transfer { + pub from_stop_id: String, + pub to_stop_id: String, + /// `None` represents a GTFS transfer explicitly marked as impossible. + pub duration: Option, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Leg { + pub trip_id: String, + pub name: String, + pub from_stop_id: String, + pub to_stop_id: String, + pub departure: u32, + pub arrival: u32, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Journey { + pub legs: Vec, +} + +impl Journey { + pub fn departure(&self) -> u32 { + self.legs.first().map_or(0, |leg| leg.departure) + } + + pub fn arrival(&self) -> u32 { + self.legs.last().map_or(0, |leg| leg.arrival) + } + + pub fn transfers(&self) -> usize { + self.legs.len().saturating_sub(1) + } + + fn score(&self) -> u32 { + self + .arrival() + .saturating_sub(self.departure()) + .saturating_add(self.transfers() as u32 * TRANSFER_PENALTY) + } +} + +#[derive(Clone)] +struct Label { + arrival: u32, + legs: Vec, +} + +/// Finds a useful timetable with a round-based public transport search. +/// +/// Each round adds one train leg, which makes the transfer limit a property of +/// the algorithm rather than a filter applied after potentially unbounded +/// exploration. For each possible departure from the origin, the result with +/// the best travel-time/transfer score is retained. +pub fn find_journeys( + trips: &[Trip], + transfers: &[Transfer], + origin: &str, + destination: &str, +) -> Vec { + let departure_times: HashSet = trips + .iter() + .flat_map(|trip| { + trip + .stop_times + .iter() + .take(trip.stop_times.len().saturating_sub(1)) + .filter(|stop_time| stop_time.stop_id == origin) + .map(|stop_time| stop_time.departure) + }) + .collect(); + + let mut journeys: Vec<_> = departure_times + .into_iter() + .filter_map(|departure| find_journey(trips, transfers, origin, destination, departure)) + .collect(); + + journeys.sort_by_key(|journey| (journey.departure(), journey.arrival())); + journeys.dedup_by(|a, b| a.legs == b.legs); + remove_dominated(journeys) +} + +fn find_journey( + trips: &[Trip], + transfers: &[Transfer], + origin: &str, + destination: &str, + departure: u32, +) -> Option { + let mut previous = HashMap::from([( + origin.to_owned(), + Label { + arrival: departure, + legs: Vec::new(), + }, + )]); + let mut candidates = Vec::new(); + + for round in 0..MAX_LEGS { + let boarding_labels = if round == 0 { + previous.clone() + } else { + labels_after_transfers(&previous, transfers) + }; + let mut current: HashMap = HashMap::new(); + + for trip in trips { + let mut boarded: Option