name: Rust

on:
  push:
    branches: ['master']
  pull_request:
    branches: ['master']

env:
  CARGO_TERM_COLOR: always
  SCCACHE_GHA_ENABLED: "true"
  RUSTC_WRAPPER: "sccache"
  CARGO_INCREMENTAL: "0"

jobs:
  build-test:
    runs-on: ubuntu-24.04
    if: ${{ github.event_name == 'pull_request' && !github.event.pull_request.draft }}
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      - uses: ./.github/actions/setup-environment
      - name: Build
        run: cargo build
      - name: Run tests
        run: cargo test --all --all-features --verbose

  check-format:
    runs-on: ubuntu-24.04
    if: ${{ github.event_name == 'pull_request' && !github.event.pull_request.draft }}
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      - name: Install rustfmt
        run: rustup component add rustfmt
      - name: Check formatting
        run: cargo fmt -- --check

  check-clippy:
    runs-on: ubuntu-24.04
    if: ${{ github.event_name == 'pull_request' && !github.event.pull_request.draft }}
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      - uses: ./.github/actions/setup-environment
      - name: Install clippy
        run: rustup component add clippy
      - name: Run clippy
        run: cargo clippy --all --all-features -- --deny clippy::all

  check-audit:
    runs-on: ubuntu-24.04
    if: ${{ github.event_name == 'pull_request' && !github.event.pull_request.draft }}
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      - uses: ./.github/actions/setup-environment
      - name: Install cargo-audit from crates.io
        uses: baptiste0928/cargo-install@v3
        with:
          crate: cargo-audit
          version: 'latest'
      - name: Run cargo audit
        run: cargo audit

  coverage:
    runs-on: ubuntu-24.04
    if: ${{ github.event_name == 'push' || !github.event.pull_request.draft }}
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      - uses: ./.github/actions/setup-environment
      - name: Install clang
        uses: awalsh128/cache-apt-pkgs-action@latest
        with:
          packages: clang clang++
          version: 1.0
      - name: Install cargo-llvm-cov from crates.io
        uses: baptiste0928/cargo-install@v3
        with:
          crate: cargo-llvm-cov
          version: '0.6.18'

      - name: Generate coverage report
        run: |
          export CC=clang
          export CXX=clang++
          cargo llvm-cov --no-fail-fast --include-ffi --workspace --lcov --output-path lcov.info

      - name: Upload to Codecov
        uses: codecov/codecov-action@v5.5.3
        continue-on-error: true
        with:
          files: lcov.info
          fail_ci_if_error: true
          token: ${{ secrets.CODECOV_TOKEN }}
          verbose: true

  test-miri:
    runs-on: ubuntu-24.04
    if: ${{ github.event_name == 'pull_request' && !github.event.pull_request.draft }}
    steps:
    - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
    - uses: ./.github/actions/setup-environment
    - name: Install Nightly Rust toolchain
      uses: actions-rs/toolchain@v1
      with:
        profile: minimal
        # Miri requires nightly Rust
        toolchain: nightly-2026-01-27
        override: true
        components: miri

    - name: Setup Miri
      run: cargo +nightly-2026-01-27 miri setup
    - name: Run tests inside Miri
      run: cargo +nightly-2026-01-27 miri test

  test-sanitizers:
      runs-on: ubuntu-24.04
      strategy:
        fail-fast: false
        matrix:
          sanitizer: [address, thread, safestack, memory]

      env:
        LSAN_OPTIONS: fast_unwind_on_malloc=0:max_leak_stack_depth=50:print_suppressions=1
        ASAN_OPTIONS: detect_leaks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1
      steps:
        - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        - uses: ./.github/actions/setup-environment
        - name: Install Nightly Rust toolchain
          uses: actions-rs/toolchain@v1
          with:
            profile: minimal
            toolchain: nightly-2026-01-27
            override: true
            components: rust-src

        - name: Run tests with ${{ matrix.sanitizer }}
          run: |
              export RUSTFLAGS="-Zsanitizer=${{ matrix.sanitizer }}"
              cargo +nightly-2026-01-27 -Zbuild-std test --target x86_64-unknown-linux-gnu --lib

  check-features-powerset:
    runs-on: ubuntu-24.04
    if: ${{ github.event_name == 'pull_request' && !github.event.pull_request.draft }}
    strategy:
      matrix:
        command:
          - check --feature-powerset --no-dev-deps --all
          - test --feature-powerset --all
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      - uses: ./.github/actions/setup-environment
      - uses: taiki-e/install-action@cargo-hack
      - name: Run cargo hack ${{ matrix.command }}
        run: cargo hack ${{ matrix.command }}
