name: Rust

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

env:
  CARGO_TERM_COLOR: always

jobs:
  test:
    name: Test on ${{ matrix.os }} (${{ matrix.arch }})
    runs-on: ${{ matrix.runner }}
    strategy:
      matrix:
        include:
          - os: linux
            arch: x86_64
            runner: ubuntu-latest
          - os: macos
            arch: x86_64
            runner: macos-latest
          - os: macos
            arch: aarch64
            runner: macos-14
          - os: freebsd
            arch: x86_64
            runner: ubuntu-latest
          - os: linux
            arch: s390x
            runner: ubuntu-latest
          - os: alpine
            arch: x86_64
            runner: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Test on Linux x86_64
        if: matrix.os == 'linux' && matrix.arch == 'x86_64'
        run: |
          cargo build --verbose
          cargo test --verbose
          cargo doc --verbose

      - name: Test on macOS
        if: matrix.os == 'macos'
        run: |
          cargo build --verbose
          cargo test --verbose
          cargo doc --verbose

      - name: Test on FreeBSD
        if: matrix.os == 'freebsd'
        uses: vmactions/freebsd-vm@v1
        with:
          usesh: true
          mem: 2048
          prepare: |
            pkg install -y curl
            curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
            echo '. ~/.cargo/env' >> ~/.profile
          run: |
            . ~/.cargo/env
            cargo build --verbose
            cargo test --verbose
            cargo doc --verbose

      - name: Test on OpenBSD
        if: matrix.os == 'openbsd'
        uses: vmactions/openbsd-vm@v1
        with:
          usesh: true
          mem: 2048
          prepare: |
            pkg_add curl
            curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
            echo '. ~/.cargo/env' >> ~/.profile
          run: |
            . ~/.cargo/env
            cargo build --verbose
            cargo test --verbose
            cargo doc --verbose

      - name: Test on Linux s390x (big-endian)
        if: matrix.os == 'linux' && matrix.arch == 's390x'
        uses: uraimo/run-on-arch-action@v2
        with:
          arch: s390x
          distro: ubuntu22.04
          githubToken: ${{ github.token }}
          install: |
            apt-get update -q -y
            apt-get install -q -y curl build-essential
            curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
            source ~/.cargo/env
          run: |
            source ~/.cargo/env
            cargo build --verbose
            cargo test --verbose
            cargo doc --verbose


      - name: Test on Alpine in Docker
        if: matrix.os == 'alpine' && matrix.arch == 'x86_64'
        run: |
          docker run --rm -i -v $PWD:/workspace -w /workspace alpine:latest sh -c "
            apk update &&
            apk add curl build-base bash &&
            curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y &&
            . /root/.cargo/env &&
            cargo build --verbose &&
            cargo test --verbose
            cargo doc --verbose
          "
