asn1 0.24.1

ASN.1 (DER) parser and writer for Rust.
Documentation
on:
  pull_request: {}
  push:
    branches: main

name: Continuous integration

permissions:
  contents: read

jobs:
  lint:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        RUST:
          - nightly
    steps:
      - uses: actions/checkout@v6.0.2
        with:
          persist-credentials: false

      - uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9
        with:
          toolchain: ${{ matrix.RUST }}
          components: rustfmt, clippy

      - uses: actions/cache@v5.0.4
        with:
          path: |
            ~/.cargo/bin/
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
            target/
          key: ${{ runner.os }}-${{ matrix.RUST }}-cargo-2-${{ hashFiles('**/Cargo.toml') }}

      - run: cargo fmt --all -- --check

      - run: cargo clippy --workspace --all-targets -- -D warnings
      - run: cargo clippy --workspace --all-targets --all-features -- -D warnings

  ci:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        RUST:
          # MSRV
          - VERSION: "1.83.0"
            FLAGS: ""

          - VERSION: stable
            FLAGS: ""
          - VERSION: stable
            FLAGS: "--no-default-features --features std"
          - VERSION: stable
            FLAGS: "--no-default-features"
            SKIP_TESTS: true
          - VERSION: beta
            FLAGS: ""
          - VERSION: beta
            FLAGS: "--no-default-features --features std"
          - VERSION: nightly
            FLAGS: ""
          - VERSION: nightly
            FLAGS: "--no-default-features --features std"
          - VERSION: nightly
            FLAGS: "-Z direct-minimal-versions"

    steps:
      - uses: actions/checkout@v6.0.2
        with:
          persist-credentials: false

      - uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9
        with:
          toolchain: ${{ matrix.RUST.VERSION }}

      - uses: actions/cache@v5.0.4
        with:
          path: |
            ~/.cargo/bin/
            ~/.cargo/git/db/
            target/
          key: ${{ runner.os }}-${{ matrix.RUST.VERSION }}-cargo-2-${{ hashFiles('**/Cargo.toml') }}

      - run: |
          cargo generate-lockfile
          cargo update -p clap --precise 4.5.61
          cargo update -p clap_lex --precise 1.0.1
        if: matrix.RUST.VERSION == '1.83.0'

      - run: cargo check --workspace --tests ${{ matrix.RUST.FLAGS }}
      - run: cargo test --workspace ${{ matrix.RUST.FLAGS }}
        if: "${{ !matrix.RUST.SKIP_TESTS }}"

  coverage:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6.0.2
        with:
          persist-credentials: false

      - uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9
        with:
          toolchain: "1.90"
          components: llvm-tools-preview

      - run: sudo apt update && sudo apt-get install -y lcov

      - uses: actions/cache@v5.0.4
        id: cargo-cache
        with:
          path: target/
          key: ${{ runner.os }}-cargo-5-${{ hashFiles('**/Cargo.toml') }}

      - run: cargo test
        env:
          RUSTFLAGS: "-Cinstrument-coverage"
          LLVM_PROFILE_FILE: "rust-cov/cov-%m-%p.profraw"

      - name: Compute coverage HTML
        run: |
          set -xe
          LIBDIR=$(rustc --print target-libdir)
          $LIBDIR/../bin/llvm-profdata merge -sparse rust-cov/*.profraw -o cargo-test-rust-cov.profdata
          $LIBDIR/../bin/llvm-cov export \
            $( \
              for file in \
                $( \
                  RUSTFLAGS="-Cinstrument-coverage" \
                    cargo test --tests --no-run --message-format=json \
                      | jq -r "select(.profile.test == true) | .filenames[]" \
                ); \
              do \
                printf "%s %s " -object $file; \
              done \
            ) \
            -instr-profile=cargo-test-rust-cov.profdata \
            --ignore-filename-regex='/.cargo/registry' \
            --ignore-filename-regex='/rustc/' \
            --ignore-filename-regex='/.rustup/toolchains/' \
            --ignore-filename-regex='/tests/' --format=lcov > cargo-test.lcov

          genhtml cargo-test.lcov -o coverage-html | tee output.log

      - uses: actions/upload-artifact@v7.0.0
        with:
          name: coverage-html
          path: coverage-html

      - name: Check coverage
        run: |
          import re
          with open("output.log") as f:
              [line] = [l for l in f if l.startswith("  lines......:")]
          coverage = float(re.search(r"([\d\.]+)%", line).group(1))
          if coverage < 100:
              raise ValueError(f"Coverage too low: {coverage}")
        shell: python