diff --git a/.circleci/config.yml b/.circleci/config.yml
deleted file mode 100644
index 426b0d0..0000000
--- a/.circleci/config.yml
+++ /dev/null
@@ -1,90 +0,0 @@
-# For a detailed guide to building and testing on iOS, read the docs:
-# https://circleci.com/docs/2.0/testing-ios/
-
-version: 2.1
-parameters:
- package-name:
- type: string
- default: "Options"
- swift-ver:
- type: string
- default: "5.3.3"
- codecov-upload-file:
- type: string
- default: "info.lcov"
-orbs:
- codecov: codecov/codecov@1.0.5
-jobs:
- build-xenial:
- machine:
- image: ubuntu-1604:201903-01
- environment:
- PACKAGE_NAME: << pipeline.parameters.package-name >>
- SWIFT_VER: << pipeline.parameters.swift-ver >>
- steps:
- - checkout
- - run:
- name: Update PATH and Define Environment Variable at Runtime
- command: |
- echo 'export RELEASE_DOT=$(lsb_release -sr)' >> $BASH_ENV
- echo 'export RELEASE_NAME=$(lsb_release -sc)' >> $BASH_ENV
- echo 'export RELEASE_NUM=${RELEASE_DOT//[-._]/}' >> $BASH_ENV
- source $BASH_ENV
- - run:
- name: Download Swift 5.2
- command: wget -q https://swift.org/builds/swift-${SWIFT_VER}-release/ubuntu${RELEASE_NUM}/swift-${SWIFT_VER}-RELEASE/swift-${SWIFT_VER}-RELEASE-ubuntu${RELEASE_DOT}.tar.gz
- - run:
- name: Extract Swift 5.2
- command: tar xzf swift-${SWIFT_VER}-RELEASE-ubuntu${RELEASE_DOT}.tar.gz
- - run:
- name: Add Path
- command: echo 'export PATH=${PWD}/swift-${SWIFT_VER}-RELEASE-ubuntu${RELEASE_DOT}/usr/bin:$PATH' >> $BASH_ENV
- - run:
- name: Resolve
- command: swift package resolve
- - run:
- name: Build
- command: swift build -v
- - run:
- name: Run tests
- command: swift test --enable-test-discovery --enable-code-coverage
- - run:
- name: Prepare Code Coverage
- command: llvm-cov export -format="lcov" .build/x86_64-unknown-linux-gnu/debug/${PACKAGE_NAME}PackageTests.xctest -instr-profile .build/debug/codecov/default.profdata > info.lcov
- - codecov/upload:
- file: << pipeline.parameters.codecov-upload-file >>
- flags: circleci,${RELEASE_NAME}
- build-catalina-11_4_1:
- macos:
- xcode: "11.4.1"
- environment:
- PACKAGE_NAME: << pipeline.parameters.package-name >>
- steps:
- - checkout
- - run:
- name: Build
- command: swift build
- - run:
- name: Lint
- command: swiftformat --lint . && swiftlint
- - run:
- name: Run Swift Package Tests
- command: swift test -v --enable-code-coverage
- - run:
- name: Prepare Code Coverage
- command: xcrun llvm-cov export -format="lcov" .build/debug/${PACKAGE_NAME}PackageTests -instr-profile .build/debug/codecov/default.profdata > info.lcov
- - codecov/upload:
- file: << pipeline.parameters.codecov-upload-file >>
- flags: circleci,macOS
- - run:
- name: Run iOS Tests
- command: xcodebuild build test -scheme ${PACKAGE_NAME}-Package -destination 'name=iPhone 11'
- - codecov/upload:
- file: << pipeline.parameters.codecov-upload-file >>
- flags: circleci,iOS
-workflows:
- version: 2
- build:
- jobs:
- #- build-catalina-11_4_1
- - build-xenial
diff --git a/.github/workflows/Options.yml b/.github/workflows/Options.yml
new file mode 100644
index 0000000..1f13ac5
--- /dev/null
+++ b/.github/workflows/Options.yml
@@ -0,0 +1,242 @@
+name: macOS
+on:
+ push:
+ branches-ignore:
+ - '*WIP'
+env:
+ PACKAGE_NAME: Options
+jobs:
+ build-ubuntu:
+ name: Build on Ubuntu
+ env:
+ PACKAGE_NAME: Options
+ SWIFT_VER: ${{ matrix.swift-version }}
+ runs-on: ${{ matrix.runs-on }}
+ if: "!contains(github.event.head_commit.message, 'ci skip')"
+ strategy:
+ matrix:
+ runs-on: [ubuntu-20.04, ubuntu-22.04]
+ swift-version: ["5.7.1", "5.8.1", "5.9", "5.9.2", "5.10"]
+ steps:
+ - uses: actions/checkout@v4
+ - name: Set Ubuntu Release DOT
+ run: echo "RELEASE_DOT=$(lsb_release -sr)" >> $GITHUB_ENV
+ - name: Set Ubuntu Release NUM
+ run: echo "RELEASE_NUM=${RELEASE_DOT//[-._]/}" >> $GITHUB_ENV
+ - name: Set Ubuntu Codename
+ run: echo "RELEASE_NAME=$(lsb_release -sc)" >> $GITHUB_ENV
+ - name: Cache swift package modules
+ id: cache-spm-linux
+ uses: actions/cache@v4
+ env:
+ cache-name: cache-spm
+ with:
+ path: .build
+ key: ${{ runner.os }}-${{ env.RELEASE_DOT }}-${{ env.cache-name }}-${{ matrix.swift-version }}-${{ hashFiles('Package.resolved') }}
+ restore-keys: |
+ ${{ runner.os }}-${{ env.RELEASE_DOT }}-${{ env.cache-name }}-${{ matrix.swift-version }}-
+ ${{ runner.os }}-${{ env.RELEASE_DOT }}-${{ env.cache-name }}-
+ - name: Cache swift
+ id: cache-swift-linux
+ uses: actions/cache@v4
+ env:
+ cache-name: cache-swift
+ with:
+ path: swift-${{ env.SWIFT_VER }}-RELEASE-ubuntu${{ env.RELEASE_DOT }}
+ key: ${{ runner.os }}-${{ env.cache-name }}-${{ matrix.swift-version }}-${{ env.RELEASE_DOT }}
+ restore-keys: |
+ ${{ runner.os }}-${{ env.cache-name }}-${{ matrix.swift-version }}-
+ - name: Download Swift
+ if: steps.cache-swift-linux.outputs.cache-hit != 'true'
+ run: curl -O https://download.swift.org/swift-${SWIFT_VER}-release/ubuntu${RELEASE_NUM}/swift-${SWIFT_VER}-RELEASE/swift-${SWIFT_VER}-RELEASE-ubuntu${RELEASE_DOT}.tar.gz
+ - name: Extract Swift
+ if: steps.cache-swift-linux.outputs.cache-hit != 'true'
+ run: tar xzf swift-${SWIFT_VER}-RELEASE-ubuntu${RELEASE_DOT}.tar.gz
+ - name: Add Path
+ run: echo "$GITHUB_WORKSPACE/swift-${SWIFT_VER}-RELEASE-ubuntu${RELEASE_DOT}/usr/bin" >> $GITHUB_PATH
+ - name: Test
+ run: swift test --enable-code-coverage
+ - uses: sersoft-gmbh/swift-coverage-action@v4
+ id: coverage-files
+ with:
+ fail-on-empty-output: true
+ - name: Upload coverage to Codecov
+ uses: codecov/codecov-action@v4
+ with:
+ fail_ci_if_error: true
+ flags: swift-${{ matrix.swift-version }},ubuntu-${{ matrix.RELEASE_DOT }}
+ verbose: true
+ token: ${{ secrets.CODECOV_TOKEN }}
+ files: ${{ join(fromJSON(steps.coverage-files.outputs.files), ',') }}
+ build-macos:
+ name: Build on macOS
+ runs-on: ${{ matrix.os }}
+ if: "!contains(github.event.head_commit.message, 'ci skip')"
+ env:
+ PACKAGE_NAME: Options
+ strategy:
+ matrix:
+ include:
+ - xcode: "/Applications/Xcode_14.1.app"
+ os: macos-12
+ iOSVersion: "16.1"
+ watchOSVersion: "9.0"
+ watchName: "Apple Watch Series 5 - 40mm"
+ iPhoneName: "iPhone 12 mini"
+ - xcode: "/Applications/Xcode_14.2.app"
+ os: macos-12
+ iOSVersion: "16.2"
+ watchOSVersion: "9.1"
+ watchName: "Apple Watch Ultra (49mm)"
+ iPhoneName: "iPhone 14"
+ - xcode: "/Applications/Xcode_15.0.1.app"
+ os: macos-13
+ iOSVersion: "17.0.1"
+ watchOSVersion: "10.0"
+ watchName: "Apple Watch Series 9 (41mm)"
+ iPhoneName: "iPhone 15"
+ - xcode: "/Applications/Xcode_15.1.app"
+ os: macos-13
+ iOSVersion: "17.2"
+ watchOSVersion: "10.2"
+ watchName: "Apple Watch Series 9 (45mm)"
+ iPhoneName: "iPhone 15 Plus"
+ - xcode: "/Applications/Xcode_15.2.app"
+ os: macos-14
+ iOSVersion: "17.2"
+ watchOSVersion: "10.2"
+ watchName: "Apple Watch Ultra (49mm)"
+ iPhoneName: "iPhone 15 Pro"
+ - xcode: "/Applications/Xcode_15.3.app"
+ os: macos-14
+ iOSVersion: "17.4"
+ watchOSVersion: "10.4"
+ watchName: "Apple Watch Ultra 2 (49mm)"
+ iPhoneName: "iPhone 15 Pro Max"
+ steps:
+ - uses: actions/checkout@v4
+ - name: Cache swift package modules
+ id: cache-spm-macos
+ uses: actions/cache@v4
+ env:
+ cache-name: cache-spm
+ with:
+ path: .build
+ key: ${{ matrix.os }}-build-${{ env.cache-name }}-${{ matrix.xcode }}-${{ hashFiles('Package.resolved') }}
+ restore-keys: |
+ ${{ matrix.os }}-build-${{ env.cache-name }}-${{ matrix.xcode }}-
+ - name: Cache mint
+ if: startsWith(matrix.xcode,'/Applications/Xcode_15.3')
+ id: cache-mint
+ uses: actions/cache@v4
+ env:
+ cache-name: cache-mint
+ with:
+ path: .mint
+ key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('Mintfile') }}
+ restore-keys: |
+ ${{ runner.os }}-build-${{ env.cache-name }}-
+ ${{ runner.os }}-build-
+ ${{ runner.os }}-
+ - name: Set Xcode Name
+ run: echo "XCODE_NAME=$(basename -- ${{ matrix.xcode }} | sed 's/\.[^.]*$//' | cut -d'_' -f2)" >> $GITHUB_ENV
+ - name: Setup Xcode
+ run: sudo xcode-select -s ${{ matrix.xcode }}/Contents/Developer
+ - name: Install mint
+ if: startsWith(matrix.xcode,'/Applications/Xcode_15.3')
+ run: |
+ brew update
+ brew install mint
+ - name: Build
+ run: swift build
+ - name: Run Swift Package tests
+ run: swift test --enable-code-coverage
+ - uses: sersoft-gmbh/swift-coverage-action@v4
+ id: coverage-files-spm
+ with:
+ fail-on-empty-output: true
+ - name: Upload coverage reports to Codecov
+ uses: codecov/codecov-action@v4
+ with:
+ files: ${{ join(fromJSON(steps.coverage-files-spm.outputs.files), ',') }}
+ token: ${{ secrets.CODECOV_TOKEN }}
+ flags: macOS,${{ env.XCODE_NAME }},${{ matrix.runs-on }}
+ - name: Clean up spm build directory
+ run: rm -rf .build
+ - name: Lint
+ run: ./scripts/lint.sh
+ if: startsWith(matrix.xcode,'/Applications/Xcode_15.3')
+ # - name: Run iOS target tests
+ # run: xcodebuild test -scheme ${{ env.PACKAGE_NAME }} -sdk "iphonesimulator" -destination 'platform=iOS Simulator,name=${{ matrix.iPhoneName }},OS=${{ matrix.iOSVersion }}' -enableCodeCoverage YES build test
+ # - uses: sersoft-gmbh/swift-coverage-action@v4
+ # id: coverage-files-iOS
+ # with:
+ # fail-on-empty-output: true
+ # - name: Upload coverage to Codecov
+ # uses: codecov/codecov-action@v4
+ # with:
+ # fail_ci_if_error: true
+ # verbose: true
+ # token: ${{ secrets.CODECOV_TOKEN }}
+ # files: ${{ join(fromJSON(steps.coverage-files-iOS.outputs.files), ',') }}
+ # flags: iOS,iOS${{ matrix.iOSVersion }},macOS,${{ env.XCODE_NAME }}
+ # - name: Run watchOS target tests
+ # run: xcodebuild test -scheme ${{ env.PACKAGE_NAME }} -sdk "watchsimulator" -destination 'platform=watchOS Simulator,name=${{ matrix.watchName }},OS=${{ matrix.watchOSVersion }}' -enableCodeCoverage YES build test
+ # - uses: sersoft-gmbh/swift-coverage-action@v4
+ # id: coverage-files-watchOS
+ # with:
+ # fail-on-empty-output: true
+ # - name: Upload coverage to Codecov
+ # uses: codecov/codecov-action@v4
+ # with:
+ # fail_ci_if_error: true
+ # verbose: true
+ # token: ${{ secrets.CODECOV_TOKEN }}
+ # files: ${{ join(fromJSON(steps.coverage-files-watchOS.outputs.files), ',') }}
+ # flags: watchOS,watchOS${{ matrix.watchOSVersion }},macOS,${{ env.XCODE_NAME }}
+ build-self:
+ name: Build on Self-Hosting macOS
+ runs-on: [self-hosted, macOS]
+ if: github.event.repository.owner.login == github.event.organization.login && !contains(github.event.head_commit.message, 'ci skip')
+ steps:
+ - uses: actions/checkout@v4
+ - name: Cache swift package modules
+ id: cache-spm-macos
+ uses: actions/cache@v4
+ env:
+ cache-name: cache-spm
+ with:
+ path: .build
+ key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('Package.resolved') }}
+ restore-keys: |
+ ${{ runner.os }}-build-${{ env.cache-name }}-
+ ${{ runner.os }}-build-
+ ${{ runner.os }}-
+ - name: Cache mint
+ id: cache-mint
+ uses: actions/cache@v4
+ env:
+ cache-name: cache-mint
+ with:
+ path: .mint
+ key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('Mintfile') }}
+ restore-keys: |
+ ${{ runner.os }}-build-${{ env.cache-name }}-
+ ${{ runner.os }}-build-
+ ${{ runner.os }}-
+ - name: Build
+ run: swift build
+ - name: Run Swift Package tests
+ run: swift test --enable-code-coverage
+ - uses: sersoft-gmbh/swift-coverage-action@v4
+ with:
+ fail-on-empty-output: true
+ - name: Upload coverage reports to Codecov
+ uses: codecov/codecov-action@v4
+ with:
+ token: ${{ secrets.CODECOV_TOKEN }}
+ flags: macOS,${{ env.XCODE_NAME }}
+ - name: Clean up spm build directory
+ run: rm -rf .build
+ - name: Lint
+ run: ./scripts/lint.sh
diff --git a/.github/workflows/arm.yml b/.github/workflows/arm.yml
deleted file mode 100644
index 5335a7d..0000000
--- a/.github/workflows/arm.yml
+++ /dev/null
@@ -1,75 +0,0 @@
-name: arm
-
-on: [push]
-
-jobs:
- build:
- env:
- PACKAGE_NAME: Options
- SWIFT_VER: 5.2.4
-
- runs-on: ubuntu-latest
- if: "!contains(github.event.head_commit.message, 'ci skip')"
-
- strategy:
- matrix:
- arch: [aarch64]
- distro: [ubuntu18.04,ubuntu20.04]
- steps:
- - uses: actions/checkout@v2
- - name: Build with Swift on arm
- uses: uraimo/run-on-arch-action@v2.0.4
- env:
- CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- with:
- arch: ${{ matrix.arch }}
- distro: ${{ matrix.distro }}
- githubToken: ${{ github.token }}
- run: |
- export DEBIAN_FRONTEND=noninteractive
- ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime
- apt update
- apt install -y curl lsb-release sudo clang git
- RELEASE_DOT=$(lsb_release -sr)
- RELEASE_NUM=${RELEASE_DOT//[-._]/}
- RELEASE_NAME=$(lsb_release -sc)
- if [[ $RELEASE_DOT == "20.04" ]]; then
- sudo apt-get -y install \
- binutils \
- git \
- gnupg2 \
- libc6-dev \
- libcurl4 \
- libedit2 \
- libgcc-9-dev \
- libpython2.7 \
- libsqlite3-0 \
- libstdc++-9-dev \
- libxml2 \
- libz3-dev \
- pkg-config \
- tzdata \
- zlib1g-dev \
- libsqlite3-dev
- else
- apt-get -y install \
- binutils \
- git \
- libc6-dev \
- libcurl4 \
- libedit2 \
- libgcc-5-dev \
- libpython2.7 \
- libsqlite3-0 \
- libstdc++-5-dev \
- libxml2 \
- pkg-config \
- tzdata \
- zlib1g-dev \
- libsqlite3-dev
- fi
- dpkg-reconfigure --frontend noninteractive tzdata
- curl -s https://packagecloud.io/install/repositories/swift-arm/release/script.deb.sh | sudo bash
- apt-get install -y swift-lang
- swift build -v
- swift test --enable-test-discovery --enable-code-coverage -v
diff --git a/.github/workflows/macOS.yml b/.github/workflows/macOS.yml
deleted file mode 100644
index 6ee36eb..0000000
--- a/.github/workflows/macOS.yml
+++ /dev/null
@@ -1,57 +0,0 @@
-name: macOS
-
-on:
- push:
- branches:
- - '*'
- - 'feature/*'
- - 'release/*'
- tags: '*'
-
-jobs:
- build:
- env:
- PACKAGE_NAME: Options
-
- runs-on: macos-latest
- if: "!contains(github.event.head_commit.message, 'ci skip')"
-
- strategy:
- matrix:
- runs-on: [macos-10.15,macos-11.0]
- xcode: ["/Applications/Xcode_11.7.app","/Applications/Xcode_12.app","/Applications/Xcode_12.1.app","/Applications/Xcode_12.2.app","/Applications/Xcode_12.3.app"]
- include:
- - os: macos-10.15
- xcode: "/Applications/Xcode_11.5.app"
- - os: macos-11.0
- xcode: "/Applications/Xcode_12.4.app"
-
- steps:
- - uses: actions/checkout@v2
- - name: Set Xcode Name
- run: echo "XCODE_NAME=$(basename -- ${{ matrix.xcode }} | sed 's/\.[^.]*$//' | cut -d'_' -f2)" >> $GITHUB_ENV
- - name: Setup Xcode
- run: sudo xcode-select -s ${{ matrix.xcode }}/Contents/Developer
- - name: Build
- run: swift build -v
- - name: Lint
- if: startsWith(github.ref, 'refs/tags/') != true
- run: swift run swiftformat --lint . && swift run swiftlint
- - name: Run tests
- run: swift test -v --enable-code-coverage
- - name: Prepare Code Coverage
- run: xcrun llvm-cov export -format="lcov" .build/debug/${{ env.PACKAGE_NAME }}PackageTests.xctest/Contents/MacOS/${{ env.PACKAGE_NAME }}PackageTests -instr-profile .build/debug/codecov/default.profdata > info.lcov
- - name: Upload to CodeCov.io
- run: bash <(curl https://codecov.io/bash) -F github -F macOS -F ${{ matrix.runs-on }}
- env:
- CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- - name: Build Documentation
- if: ${{ matrix.os == 'macos-11.0' && matrix.xcode == '/Applications/Xcode_12.4.app' && !startsWith(github.ref, 'refs/tags/') }}
- run: |
- swift run sourcedocs generate build -cra
- git config --local user.email "action@github.com"
- git config --local user.name "GitHub Action"
- git status
- git add Documentation
- git diff-index --quiet HEAD || git commit -m "[github action] Update Docs"
- git push
diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml
deleted file mode 100644
index 4c72419..0000000
--- a/.github/workflows/ubuntu.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-name: ubuntu
-
-on: [push]
-
-jobs:
- build:
- env:
- PACKAGE_NAME: Options
- SWIFT_VER: ${{ matrix.swift-version }}
-
- runs-on: ${{ matrix.runs-on }}
- if: "!contains(github.event.head_commit.message, 'ci skip')"
-
- strategy:
- matrix:
- runs-on: [ubuntu-18.04,ubuntu-20.04]
- swift-version: [5.2.5, 5.3.3]
- steps:
- - uses: actions/checkout@v2
- - name: Set Ubuntu Release DOT
- run: echo "RELEASE_DOT=$(lsb_release -sr)" >> $GITHUB_ENV
- - name: Set Ubuntu Release NUM
- run: echo "RELEASE_NUM=${RELEASE_DOT//[-._]/}" >> $GITHUB_ENV
- - name: Set Ubuntu Codename
- run: echo "RELEASE_NAME=$(lsb_release -sc)" >> $GITHUB_ENV
- - name: Download Swift
- run: curl -O https://swift.org/builds/swift-${SWIFT_VER}-release/ubuntu${RELEASE_NUM}/swift-${SWIFT_VER}-RELEASE/swift-${SWIFT_VER}-RELEASE-ubuntu${RELEASE_DOT}.tar.gz
- - name: Extract Swift
- run: tar xzf swift-${SWIFT_VER}-RELEASE-ubuntu${RELEASE_DOT}.tar.gz
- - name: Add Path
- run: echo "$GITHUB_WORKSPACE/swift-${SWIFT_VER}-RELEASE-ubuntu${RELEASE_DOT}/usr/bin" >> $GITHUB_PATH
- - name: Build
- run: swift build
- - name: Run tests
- run: swift test --enable-test-discovery --enable-code-coverage
- - name: Prepare Code Coverage
- run: llvm-cov export -format="lcov" .build/x86_64-unknown-linux-gnu/debug/${{ env.PACKAGE_NAME }}PackageTests.xctest -instr-profile .build/debug/codecov/default.profdata > info.lcov
- - name: Upload to CodeCov.io
- run: bash <(curl https://codecov.io/bash) -F github -F ${RELEASE_NAME} -F ${SWIFT_VER}
- env:
- CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
diff --git a/.gitignore b/.gitignore
index 1ffb7cf..bd44408 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,18 +1,16 @@
-# Created by https://www.gitignore.io/api/swiftpm,swiftpackagemanager,xcode,swift,macos
-# Edit at https://www.gitignore.io/?templates=swiftpm,swiftpackagemanager,xcode,swift,macos
-
+# Created by https://www.toptal.com/developers/gitignore/api/swift,swiftpm,swiftpackagemanager,xcode,macos
+# Edit at https://www.toptal.com/developers/gitignore?templates=swift,swiftpm,swiftpackagemanager,xcode,macos
### macOS ###
# General
.DS_Store
-*.DS_Store
-
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
+
# Thumbnails
._*
@@ -32,20 +30,26 @@ Network Trash Folder
Temporary Items
.apdisk
+### macOS Patch ###
+# iCloud generated files
+*.icloud
+
### Swift ###
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
-## Build generated
-build/
-DerivedData/
+## User settings
+xcuserdata/
-## Various settings
-# Xcode
-#
-build/
+## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
+*.xcscmblueprint
+*.xccheckout
+## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
+build/
+DerivedData/
+*.moved-aside
*.pbxuser
!default.pbxuser
*.mode1v3
@@ -54,17 +58,11 @@ build/
!default.mode2v3
*.perspectivev3
!default.perspectivev3
-xcuserdata/
-
-## Other
-*.moved-aside
-*.xccheckout
-*.xcuserstate
-
-*.xcscmblueprint
## Obj-C/Swift specific
*.hmap
+
+## App packaging
*.ipa
*.dSYM.zip
*.dSYM
@@ -74,43 +72,45 @@ timeline.xctimeline
playground.xcworkspace
# Swift Package Manager
+#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
# Package.resolved
+*.xcodeproj
+#
+# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
+# hence it is not needed unless you have added a package configuration file to your project
+.swiftpm
+
.build/
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
# CocoaPods
-
+#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
-
-Example/Pods/
-Example/*.xcworkspace
+#
+# Pods/
+#
+# Add this line if you want to avoid checking in source code from the Xcode workspace
+# *.xcworkspace
# Carthage
-
+#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts
-Carthage/Build
+Carthage/Build/
# Accio dependency management
Dependencies/
.accio/
# fastlane
-
-# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
-# screenshots whenever they are needed.
+#
+# It is recommended to not store the screenshots in the git repo.
+# Instead, use fastlane to re-generate the screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control
@@ -120,50 +120,11 @@ fastlane/screenshots/**/*.png
fastlane/test_output
# Code Injection
+#
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode
-VCS.swift
iOSInjectionProject/
-Products
-
-
-### SwiftPackageManager ###
-Packages
-xcuserdata
-/*.xcodeproj
-.tmp
-
-
-### SwiftPM ###
-
-
-### Xcode ###
-# Xcode
-# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
-
-## User settings
-
-## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
-
-## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
-
-## Xcode Patch
-/*.xcodeproj/*
-.swiftpm
-!*.xcodeproj/project.pbxproj
-!*.xcodeproj/xcshareddata/
-!*.xcworkspace/contents.xcworkspacedata
-/*.gcno
-
-### Xcode Patch ###
-**/xcshareddata/WorkspaceSettings.xcsettings
-
-# End of https://www.gitignore.io/api/swiftpm,swiftpackagemanager,xcode,swift,macos
-*.xcworkspace
-Pods
-*.lcov
-Brewfile.lock.json
-Package.resolved
-gh-md-toc
+.mint
+Output
\ No newline at end of file
diff --git a/.periphery.yml b/.periphery.yml
new file mode 100644
index 0000000..85b884a
--- /dev/null
+++ b/.periphery.yml
@@ -0,0 +1 @@
+retain_public: true
diff --git a/.spi.yml b/.spi.yml
new file mode 100644
index 0000000..e65a103
--- /dev/null
+++ b/.spi.yml
@@ -0,0 +1,4 @@
+version: 1
+builder:
+ configs:
+ - documentation_targets: [SimulatorServices]
diff --git a/.swift-version b/.swift-version
index 7ed6ff8..760606e 100644
--- a/.swift-version
+++ b/.swift-version
@@ -1 +1 @@
-5
+5.7
diff --git a/.swiftformat b/.swiftformat
index 7001c5e..c510d49 100644
--- a/.swiftformat
+++ b/.swiftformat
@@ -1,7 +1,7 @@
--indent 2
---header strip
+--header "\n .*?\.swift\n SimulatorServices\n\n Created by Leo Dion.\n Copyright © {year} BrightDigit.\n\n Permission is hereby granted, free of charge, to any person\n obtaining a copy of this software and associated documentation\n files (the “Software”), to deal in the Software without\n restriction, including without limitation the rights to use,\n copy, modify, merge, publish, distribute, sublicense, and/or\n sell copies of the Software, and to permit persons to whom the\n Software is furnished to do so, subject to the following\n conditions:\n \n The above copyright notice and this permission notice shall be\n included in all copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,\n EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n OTHER DEALINGS IN THE SOFTWARE.\n"
--commas inline
---disable wrapMultilineStatementBraces
---extensionacl on-extension
+--disable wrapMultilineStatementBraces, redundantInternal
+--extensionacl on-declarations
--decimalgrouping 3,4
---exclude .build, DerivedData
+--exclude .build, DerivedData, .swiftpm
diff --git a/.swiftlint.yml b/.swiftlint.yml
index 981984b..aebc975 100644
--- a/.swiftlint.yml
+++ b/.swiftlint.yml
@@ -1,5 +1,4 @@
opt_in_rules:
- - anyobject_protocol
- array_init
- attributes
- closure_body_length
@@ -22,11 +21,9 @@ opt_in_rules:
- expiring_todo
- explicit_acl
- explicit_init
- - explicit_self
- explicit_top_level_acl
- fallthrough
- fatal_error_message
- - file_header
- file_name
- file_name_no_space
- file_types_order
@@ -38,6 +35,7 @@ opt_in_rules:
- identical_operands
- implicit_return
- implicitly_unwrapped_optional
+ - indentation_width
- joined_default_parameter
- last_where
- legacy_multiple
@@ -80,7 +78,6 @@ opt_in_rules:
- static_operator
- strict_fileprivate
- strong_iboutlet
- - switch_case_on_newline
- toggle_bool
- trailing_closure
- type_contents_order
@@ -88,23 +85,24 @@ opt_in_rules:
- unneeded_parentheses_in_closure_argument
- unowned_variable_capture
- untyped_error_in_catch
- - unused_declaration
- - unused_import
- vertical_parameter_alignment_on_call
- - vertical_whitespace_between_cases
- vertical_whitespace_closing_braces
- vertical_whitespace_opening_braces
- xct_specific_matcher
- yoda_condition
-cyclomatic_complexity:
- - 6
- - 9
+analyzer_rules:
+ - explicit_self
+ - unused_declaration
+ - unused_import
+type_body_length:
+ - 100
+ - 200
file_length:
- 200
- - 550
+ - 300
function_body_length:
- - 15
- - 25
+ - 18
+ - 40
function_parameter_count: 8
line_length:
- 90
@@ -113,9 +111,9 @@ identifier_name:
excluded:
- id
excluded:
- - Tests/**/XCTestManifests.swift
- - Tests/LinuxMain.swift
+ - Tests
- DerivedData
- .build
+ - .swiftpm
indentation_width:
indentation_width: 2
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 455bc95..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-jobs:
- include:
- - os: linux
- dist: bionic
- arch: amd64
- - os: linux
- dist: focal
- arch: amd64
- - os: linux
- dist: bionic
- arch: arm64
- - os: linux
- dist: focal
- arch: arm64
- - os: osx
- osx_image: xcode11.4
- - os: osx
- osx_image: xcode11.5
- - os: osx
- osx_image: xcode11.6
- - os: osx
- osx_image: xcode12
-env:
- global:
- - FRAMEWORK_NAME=Options
- - SWIFT_VER=5.3.3
-before_install:
- - bash -e ./Scripts/before_install.sh
-script:
- - bash -e ./Scripts/script.sh
diff --git a/Mintfile b/Mintfile
new file mode 100644
index 0000000..c1dc548
--- /dev/null
+++ b/Mintfile
@@ -0,0 +1,2 @@
+nicklockwood/SwiftFormat@0.53.5
+realm/SwiftLint@0.54.0
\ No newline at end of file
diff --git a/Package.swift b/Package.swift
index 4b5c863..5646b68 100644
--- a/Package.swift
+++ b/Package.swift
@@ -1,8 +1,7 @@
-// swift-tools-version:5.2
+// swift-tools-version: 5.7.1
// swiftlint:disable explicit_top_level_acl
// swiftlint:disable prefixed_toplevel_constant
-// swiftlint:disable line_length
// swiftlint:disable explicit_acl
import PackageDescription
@@ -17,13 +16,6 @@ let package = Package(
],
dependencies: [
// Dependencies declare other packages that this package depends on.
- // .package(url: /* package url */, from: "1.0.0")
- .package(url: "https://github.com/shibapm/Komondor", from: "1.0.6"), // dev
- .package(url: "https://github.com/eneko/SourceDocs", from: "1.2.1"), // dev
- .package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.47.0"), // dev
- .package(url: "https://github.com/realm/SwiftLint", from: "0.41.0"), // dev
- .package(url: "https://github.com/shibapm/Rocket", .branch("master")), // dev
- .package(url: "https://github.com/mattpolzin/swift-test-codecov", .branch("master")) // dev
],
targets: [
.target(
@@ -37,28 +29,6 @@ let package = Package(
]
)
-#if canImport(PackageConfig)
- import PackageConfig
-
- let requiredCoverage: Int = 90
-
- let config = PackageConfiguration([
- "komondor": [
- "pre-push": [
- "swift test --enable-code-coverage --enable-test-discovery",
- "swift run swift-test-codecov .build/debug/codecov/Options.json -v \(requiredCoverage)"
- ],
- "pre-commit": [
- "swift test --generate-linuxmain",
- "swift test --enable-code-coverage --enable-test-discovery",
- "swift run swift-test-codecov .build/debug/codecov/Options.json -v \(requiredCoverage)",
- "swift run swiftformat .",
- "swift run swiftlint autocorrect",
- "swift run sourcedocs generate build -cra",
- "git add .",
- "swift run swiftformat --lint .",
- "swift run swiftlint --strict"
- ]
- ]
- ]).write()
-#endif
+// swiftlint:enable explicit_top_level_acl
+// swiftlint:enable prefixed_toplevel_constant
+// swiftlint:enable explicit_acl
diff --git a/Package@swift-5.10.swift b/Package@swift-5.10.swift
new file mode 100644
index 0000000..da62733
--- /dev/null
+++ b/Package@swift-5.10.swift
@@ -0,0 +1,65 @@
+// swift-tools-version: 5.10
+
+// swiftlint:disable explicit_top_level_acl
+// swiftlint:disable prefixed_toplevel_constant
+// swiftlint:disable explicit_acl
+
+import CompilerPluginSupport
+import PackageDescription
+
+let swiftSettings = [
+ SwiftSetting.enableUpcomingFeature("BareSlashRegexLiterals"),
+ SwiftSetting.enableUpcomingFeature("ConciseMagicFile"),
+ SwiftSetting.enableUpcomingFeature("ExistentialAny"),
+ SwiftSetting.enableUpcomingFeature("ForwardTrailingClosures"),
+ SwiftSetting.enableUpcomingFeature("ImplicitOpenExistentials"),
+ SwiftSetting.enableUpcomingFeature("StrictConcurrency"),
+ SwiftSetting.enableUpcomingFeature("DisableOutwardActorInference"),
+ SwiftSetting.enableExperimentalFeature("StrictConcurrency")
+]
+
+let package = Package(
+ name: "Options",
+ platforms: [
+ .macOS(.v10_15),
+ .iOS(.v13),
+ .tvOS(.v13),
+ .watchOS(.v6),
+ .macCatalyst(.v13),
+ .visionOS(.v1)
+ ],
+ products: [
+ .library(
+ name: "Options",
+ targets: ["Options"]
+ )
+ ],
+ dependencies: [
+ .package(url: "https://github.com/apple/swift-syntax", from: "510.0.0")
+ // Dependencies declare other packages that this package depends on.
+ // .package(url: /* package url */, from: "1.0.0")
+ ],
+ targets: [
+ .target(
+ name: "Options",
+ dependencies: ["OptionsMacros"],
+ swiftSettings: swiftSettings
+ ),
+ .macro(
+ name: "OptionsMacros",
+ dependencies: [
+ .product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
+ .product(name: "SwiftCompilerPlugin", package: "swift-syntax")
+ ],
+ swiftSettings: swiftSettings
+ ),
+ .testTarget(
+ name: "OptionsTests",
+ dependencies: ["Options"]
+ )
+ ]
+)
+
+// swiftlint:enable explicit_top_level_acl
+// swiftlint:enable prefixed_toplevel_constant
+// swiftlint:enable explicit_acl
diff --git a/Scripts/Dockerfile b/Scripts/Dockerfile
deleted file mode 100644
index 72a918b..0000000
--- a/Scripts/Dockerfile
+++ /dev/null
@@ -1,6 +0,0 @@
-# Dockerfile
-ARG TAG=latest
-FROM swift:${TAG}
-RUN apt-get update && apt-get install --no-install-recommends -y libsqlite3-dev \
- && apt-get clean \
- && rm -rf /var/lib/apt/lists/*
diff --git a/Scripts/before_install.sh b/Scripts/before_install.sh
deleted file mode 100644
index 3365229..0000000
--- a/Scripts/before_install.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/bash
-
-if [[ $TRAVIS_OS_NAME = 'osx' ]]; then
- :
-elif [[ $TRAVIS_OS_NAME = 'linux' ]]; then
- RELEASE_DOT=$(lsb_release -sr)
- RELEASE_NUM=${RELEASE_DOT//[-._]/}
-
- if [[ $RELEASE_DOT == "20.04" ]]; then
- sudo apt-get update
- sudo apt-get -y install \
- binutils \
- git \
- gnupg2 \
- libc6-dev \
- libcurl4 \
- libedit2 \
- libgcc-9-dev \
- libpython2.7 \
- libsqlite3-0 \
- libstdc++-9-dev \
- libxml2 \
- libz3-dev \
- pkg-config \
- tzdata \
- zlib1g-dev
- fi
-
- if [[ $TRAVIS_CPU_ARCH == "arm64" ]]; then
- curl -s https://packagecloud.io/install/repositories/swift-arm/release/script.deb.sh | sudo bash
- sudo apt-get install swift-lang
- else
- wget https://swift.org/builds/swift-${SWIFT_VER}-release/ubuntu${RELEASE_NUM}/swift-${SWIFT_VER}-RELEASE/swift-${SWIFT_VER}-RELEASE-ubuntu${RELEASE_DOT}.tar.gz
- tar xzf swift-${SWIFT_VER}-RELEASE-ubuntu${RELEASE_DOT}.tar.gz
- fi
-fi
diff --git a/Scripts/docc.sh b/Scripts/docc.sh
new file mode 100755
index 0000000..3e4c918
--- /dev/null
+++ b/Scripts/docc.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+xcodebuild docbuild -scheme SimulatorServices -derivedDataPath DerivedData -destination 'platform=macOS'
+$(xcrun --find docc) process-archive transform-for-static-hosting DerivedData/Build/Products/Debug/SimulatorServices.doccarchive --output-path Output
\ No newline at end of file
diff --git a/Scripts/gh-md-toc b/Scripts/gh-md-toc
new file mode 100755
index 0000000..8d35839
--- /dev/null
+++ b/Scripts/gh-md-toc
@@ -0,0 +1,411 @@
+#!/usr/bin/env bash
+
+#
+# Steps:
+#
+# 1. Download corresponding html file for some README.md:
+# curl -s $1
+#
+# 2. Discard rows where no substring 'user-content-' (github's markup):
+# awk '/user-content-/ { ...
+#
+# 3.1 Get last number in each row like ' ... sitemap.js.*<\/h/)+2, RLENGTH-5)
+#
+# 5. Find anchor and insert it inside "(...)":
+# substr($0, match($0, "href=\"[^\"]+?\" ")+6, RLENGTH-8)
+#
+
+gh_toc_version="0.8.0"
+
+gh_user_agent="gh-md-toc v$gh_toc_version"
+
+#
+# Download rendered into html README.md by its url.
+#
+#
+gh_toc_load() {
+ local gh_url=$1
+
+ if type curl &>/dev/null; then
+ curl --user-agent "$gh_user_agent" -s "$gh_url"
+ elif type wget &>/dev/null; then
+ wget --user-agent="$gh_user_agent" -qO- "$gh_url"
+ else
+ echo "Please, install 'curl' or 'wget' and try again."
+ exit 1
+ fi
+}
+
+#
+# Converts local md file into html by GitHub
+#
+# -> curl -X POST --data '{"text": "Hello world github/linguist#1 **cool**, and #1!"}' https://api.github.com/markdown
+#
Hello world github/linguist#1 cool, and #1!
'"
+gh_toc_md2html() {
+ local gh_file_md=$1
+ local skip_header=$2
+
+ URL=https://api.github.com/markdown/raw
+
+ if [ ! -z "$GH_TOC_TOKEN" ]; then
+ TOKEN=$GH_TOC_TOKEN
+ else
+ TOKEN_FILE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/token.txt"
+ if [ -f "$TOKEN_FILE" ]; then
+ TOKEN="$(cat $TOKEN_FILE)"
+ fi
+ fi
+ if [ ! -z "${TOKEN}" ]; then
+ AUTHORIZATION="Authorization: token ${TOKEN}"
+ fi
+
+ local gh_tmp_file_md=$gh_file_md
+ if [ "$skip_header" = "yes" ]; then
+ if grep -Fxq "" $gh_src; then
+ # cut everything before the toc
+ gh_tmp_file_md=$gh_file_md~~
+ sed '1,//d' $gh_file_md > $gh_tmp_file_md
+ fi
+ fi
+
+ # echo $URL 1>&2
+ OUTPUT=$(curl -s \
+ --user-agent "$gh_user_agent" \
+ --data-binary @"$gh_tmp_file_md" \
+ -H "Content-Type:text/plain" \
+ -H "$AUTHORIZATION" \
+ "$URL")
+
+ rm -f $gh_file_md~~
+
+ if [ "$?" != "0" ]; then
+ echo "XXNetworkErrorXX"
+ fi
+ if [ "$(echo "${OUTPUT}" | awk '/API rate limit exceeded/')" != "" ]; then
+ echo "XXRateLimitXX"
+ else
+ echo "${OUTPUT}"
+ fi
+}
+
+
+#
+# Is passed string url
+#
+gh_is_url() {
+ case $1 in
+ https* | http*)
+ echo "yes";;
+ *)
+ echo "no";;
+ esac
+}
+
+#
+# TOC generator
+#
+gh_toc(){
+ local gh_src=$1
+ local gh_src_copy=$1
+ local gh_ttl_docs=$2
+ local need_replace=$3
+ local no_backup=$4
+ local no_footer=$5
+ local indent=$6
+ local skip_header=$7
+
+ if [ "$gh_src" = "" ]; then
+ echo "Please, enter URL or local path for a README.md"
+ exit 1
+ fi
+
+
+ # Show "TOC" string only if working with one document
+ if [ "$gh_ttl_docs" = "1" ]; then
+
+ echo "Table of Contents"
+ echo "================="
+ echo ""
+ gh_src_copy=""
+
+ fi
+
+ if [ "$(gh_is_url "$gh_src")" == "yes" ]; then
+ gh_toc_load "$gh_src" | gh_toc_grab "$gh_src_copy" "$indent"
+ if [ "${PIPESTATUS[0]}" != "0" ]; then
+ echo "Could not load remote document."
+ echo "Please check your url or network connectivity"
+ exit 1
+ fi
+ if [ "$need_replace" = "yes" ]; then
+ echo
+ echo "!! '$gh_src' is not a local file"
+ echo "!! Can't insert the TOC into it."
+ echo
+ fi
+ else
+ local rawhtml=$(gh_toc_md2html "$gh_src" "$skip_header")
+ if [ "$rawhtml" == "XXNetworkErrorXX" ]; then
+ echo "Parsing local markdown file requires access to github API"
+ echo "Please make sure curl is installed and check your network connectivity"
+ exit 1
+ fi
+ if [ "$rawhtml" == "XXRateLimitXX" ]; then
+ echo "Parsing local markdown file requires access to github API"
+ echo "Error: You exceeded the hourly limit. See: https://developer.github.com/v3/#rate-limiting"
+ TOKEN_FILE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/token.txt"
+ echo "or place GitHub auth token here: ${TOKEN_FILE}"
+ exit 1
+ fi
+ local toc=`echo "$rawhtml" | gh_toc_grab "$gh_src_copy" "$indent"`
+ echo "$toc"
+ if [ "$need_replace" = "yes" ]; then
+ if grep -Fxq "" $gh_src && grep -Fxq "" $gh_src; then
+ echo "Found markers"
+ else
+ echo "You don't have or in your file...exiting"
+ exit 1
+ fi
+ local ts="<\!--ts-->"
+ local te="<\!--te-->"
+ local dt=`date +'%F_%H%M%S'`
+ local ext=".orig.${dt}"
+ local toc_path="${gh_src}.toc.${dt}"
+ local toc_createdby=""
+ local toc_footer=""
+ # http://fahdshariff.blogspot.ru/2012/12/sed-mutli-line-replacement-between-two.html
+ # clear old TOC
+ sed -i${ext} "/${ts}/,/${te}/{//!d;}" "$gh_src"
+ # create toc file
+ echo "${toc}" > "${toc_path}"
+ if [ "${no_footer}" != "yes" ]; then
+ echo -e "\n${toc_createdby}\n${toc_footer}\n" >> "$toc_path"
+ fi
+
+ # insert toc file
+ if ! sed --version > /dev/null 2>&1; then
+ sed -i "" "/${ts}/r ${toc_path}" "$gh_src"
+ else
+ sed -i "/${ts}/r ${toc_path}" "$gh_src"
+ fi
+ echo
+ if [ "${no_backup}" = "yes" ]; then
+ rm ${toc_path} ${gh_src}${ext}
+ fi
+ echo "!! TOC was added into: '$gh_src'"
+ if [ -z "${no_backup}" ]; then
+ echo "!! Origin version of the file: '${gh_src}${ext}'"
+ echo "!! TOC added into a separate file: '${toc_path}'"
+ fi
+ echo
+ fi
+ fi
+}
+
+#
+# Grabber of the TOC from rendered html
+#
+# $1 - a source url of document.
+# It's need if TOC is generated for multiple documents.
+# $2 - number of spaces used to indent.
+#
+gh_toc_grab() {
+ common_awk_script='
+ modified_href = ""
+ split(href, chars, "")
+ for (i=1;i <= length(href); i++) {
+ c = chars[i]
+ res = ""
+ if (c == "+") {
+ res = " "
+ } else {
+ if (c == "%") {
+ res = "\\x"
+ } else {
+ res = c ""
+ }
+ }
+ modified_href = modified_href res
+ }
+ print sprintf("%*s", (level-1)*'"$2"', "") "* [" text "](" gh_url modified_href ")"
+ '
+ if [ `uname -s` == "OS/390" ]; then
+ grepcmd="pcregrep -o"
+ echoargs=""
+ awkscript='{
+ level = substr($0, length($0), 1)
+ text = substr($0, match($0, /a>.*<\/h/)+2, RLENGTH-5)
+ href = substr($0, match($0, "href=\"([^\"]+)?\"")+6, RLENGTH-7)
+ '"$common_awk_script"'
+ }'
+ else
+ grepcmd="grep -Eo"
+ echoargs="-e"
+ awkscript='{
+ level = substr($0, length($0), 1)
+ text = substr($0, match($0, /a>.*<\/h/)+2, RLENGTH-5)
+ href = substr($0, match($0, "href=\"[^\"]+?\"")+6, RLENGTH-7)
+ '"$common_awk_script"'
+ }'
+ fi
+ href_regex='href=\"[^\"]+?\"'
+
+ # if closed is on the new line, then move it on the prev line
+ # for example:
+ # was: The command foo1
+ #
+ # became: The command foo1
+ sed -e ':a' -e 'N' -e '$!ba' -e 's/\n<\/h/<\/h/g' |
+
+ # find strings that corresponds to template
+ $grepcmd '//g' | sed 's/<\/code>//g' |
+
+ # remove g-emoji
+ sed 's/]*[^<]*<\/g-emoji> //g' |
+
+ # now all rows are like:
+ # ... /dev/null`; then
+ echo `$tool --version | head -n 1`
+ else
+ echo "not installed"
+ fi
+ done
+}
+
+show_help() {
+ local app_name=$(basename "$0")
+ echo "GitHub TOC generator ($app_name): $gh_toc_version"
+ echo ""
+ echo "Usage:"
+ echo " $app_name [options] src [src] Create TOC for a README file (url or local path)"
+ echo " $app_name - Create TOC for markdown from STDIN"
+ echo " $app_name --help Show help"
+ echo " $app_name --version Show version"
+ echo ""
+ echo "Options:"
+ echo " --indent Set indent size. Default: 3."
+ echo " --insert Insert new TOC into original file. For local files only. Default: false."
+ echo " See https://github.com/ekalinin/github-markdown-toc/issues/41 for details."
+ echo " --no-backup Remove backup file. Set --insert as well. Default: false."
+ echo " --hide-footer Do not write date & author of the last TOC update. Set --insert as well. Default: false."
+ echo " --skip-header Hide entry of the topmost headlines. Default: false."
+ echo " See https://github.com/ekalinin/github-markdown-toc/issues/125 for details."
+ echo ""
+}
+
+#
+# Options handlers
+#
+gh_toc_app() {
+ local need_replace="no"
+ local indent=3
+
+ if [ "$1" = '--help' ] || [ $# -eq 0 ] ; then
+ show_help
+ return
+ fi
+
+ if [ "$1" = '--version' ]; then
+ show_version
+ return
+ fi
+
+ if [ "$1" = '--indent' ]; then
+ indent="$2"
+ shift 2
+ fi
+
+ if [ "$1" = "-" ]; then
+ if [ -z "$TMPDIR" ]; then
+ TMPDIR="/tmp"
+ elif [ -n "$TMPDIR" -a ! -d "$TMPDIR" ]; then
+ mkdir -p "$TMPDIR"
+ fi
+ local gh_tmp_md
+ if [ `uname -s` == "OS/390" ]; then
+ local timestamp=$(date +%m%d%Y%H%M%S)
+ gh_tmp_md="$TMPDIR/tmp.$timestamp"
+ else
+ gh_tmp_md=$(mktemp $TMPDIR/tmp.XXXXXX)
+ fi
+ while read input; do
+ echo "$input" >> "$gh_tmp_md"
+ done
+ gh_toc_md2html "$gh_tmp_md" | gh_toc_grab "" "$indent"
+ return
+ fi
+
+ if [ "$1" = '--insert' ]; then
+ need_replace="yes"
+ shift
+ fi
+
+ if [ "$1" = '--no-backup' ]; then
+ need_replace="yes"
+ no_backup="yes"
+ shift
+ fi
+
+ if [ "$1" = '--hide-footer' ]; then
+ need_replace="yes"
+ no_footer="yes"
+ shift
+ fi
+
+ if [ "$1" = '--skip-header' ]; then
+ skip_header="yes"
+ shift
+ fi
+
+
+ for md in "$@"
+ do
+ echo ""
+ gh_toc "$md" "$#" "$need_replace" "$no_backup" "$no_footer" "$indent" "$skip_header"
+ done
+
+ echo ""
+ echo ""
+}
+
+#
+# Entry point
+#
+gh_toc_app "$@"
diff --git a/Scripts/images.sh b/Scripts/images.sh
deleted file mode 100755
index 1af0249..0000000
--- a/Scripts/images.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-
-swift_versions=('5.3' '5.2')
-ubuntu_versions=('bionic' 'xenial' 'focal')
-
-for swift_version in ${swift_versions[@]}
-do
- for ubuntu_version in ${ubuntu_versions[@]}
- do
- (
- docker build -t brightdigit/mistkit-sql:$swift_version-$ubuntu_version . --build-arg TAG=$swift_version-$ubuntu_version
- docker push brightdigit/mistkit-sql:$swift_version-$ubuntu_version
- ) &
- done
-done
-wait
diff --git a/Scripts/lint.sh b/Scripts/lint.sh
new file mode 100755
index 0000000..fd0a0e3
--- /dev/null
+++ b/Scripts/lint.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+if [ -z "$SRCROOT" ]; then
+ SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
+ PACKAGE_DIR="${SCRIPT_DIR}/.."
+else
+ PACKAGE_DIR="${SRCROOT}"
+fi
+
+if [ -z "$GITHUB_ACTION" ]; then
+ MINT_CMD="/opt/homebrew/bin/mint"
+else
+ MINT_CMD="mint"
+fi
+
+export MINT_PATH="$PACKAGE_DIR/.mint"
+MINT_ARGS="-n -m $PACKAGE_DIR/Mintfile --silent"
+MINT_RUN="$MINT_CMD run $MINT_ARGS"
+
+pushd $PACKAGE_DIR
+
+$MINT_CMD bootstrap -m Mintfile
+
+if [ "$LINT_MODE" == "NONE" ]; then
+ exit
+elif [ "$LINT_MODE" == "STRICT" ]; then
+ SWIFTFORMAT_OPTIONS=""
+ SWIFTLINT_OPTIONS="--strict"
+else
+ SWIFTFORMAT_OPTIONS=""
+ SWIFTLINT_OPTIONS=""
+fi
+
+pushd $PACKAGE_DIR
+
+if [ -z "$CI" ]; then
+ $MINT_RUN swiftformat .
+ $MINT_RUN swiftlint autocorrect
+fi
+
+$MINT_RUN swiftformat --lint $SWIFTFORMAT_OPTIONS .
+$MINT_RUN swiftlint lint $SWIFTLINT_OPTIONS
+
+popd
diff --git a/Scripts/script.sh b/Scripts/script.sh
deleted file mode 100644
index 8915708..0000000
--- a/Scripts/script.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/bash
-
-if [[ $TRAVIS_OS_NAME = 'osx' ]]; then
- swift run swiftformat --lint . && swift run swiftlint
-elif [[ $TRAVIS_OS_NAME = 'linux' ]]; then
- # What to do in Ubunutu
- RELEASE_DOT=$(lsb_release -sr)
- RELEASE_NUM=${RELEASE_DOT//[-._]/}
- RELEASE_NAME=$(lsb_release -sc)
- [[ $TRAVIS_CPU_ARCH = "arm64" ]] && ARCH_PREFIX="aarch64" || ARCH_PREFIX="x86_64"
- export PATH="${PWD}/swift-${SWIFT_VER}-RELEASE-ubuntu${RELEASE_DOT}/usr/bin:$PATH"
-fi
-
-ARCH=${TRAVIS_CPU_ARCH:-amd64}
-[[ $TRAVIS_CPU_ARCH = "arm64" ]] && ARCH_PREFIX="aarch64" || ARCH_PREFIX="x86_64"
-
-swift build
-swift test --enable-code-coverage --enable-test-discovery
-
-if [[ $TRAVIS_OS_NAME = 'osx' ]]; then
- xcrun llvm-cov export -format="lcov" .build/debug/${FRAMEWORK_NAME}PackageTests.xctest/Contents/MacOS/${FRAMEWORK_NAME}PackageTests -instr-profile .build/debug/codecov/default.profdata > info.lcov
- bash <(curl https://codecov.io/bash) -F travis -F macOS -n $TRAVIS_JOB_NUMBER-$TRAVIS_OS_NAME
-else
- llvm-cov export -format="lcov" .build/${ARCH_PREFIX}-unknown-linux-gnu/debug/${FRAMEWORK_NAME}PackageTests.xctest -instr-profile .build/debug/codecov/default.profdata > info.lcov
- bash <(curl https://codecov.io/bash) -F travis -F $RELEASE_NAME -F $ARCH -n $TRAVIS_JOB_NUMBER-$TRAVIS_OS_NAME
-fi
-
-# curl -s https://raw.githubusercontent.com/daveverwer/SwiftPMLibrary/master/script.sh | bash -s -- mine
-
-# if [[ $TRAVIS_OS_NAME = 'osx' ]]; then
-# pod lib lint
-# swift package generate-xcodeproj
-# xcodebuild -quiet -workspace Example/Example.xcworkspace -scheme "iOS_Example" ONLY_ACTIVE_ARCH=NO CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO
-# xcodebuild -quiet -workspace Example/Example.xcworkspace -scheme "tvOS_Example" ONLY_ACTIVE_ARCH=NO CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO
-# xcodebuild -quiet -workspace Example/Example.xcworkspace -scheme "macOS_Example" ONLY_ACTIVE_ARCH=NO CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO
-# fi
diff --git a/Sources/Options/Array.swift b/Sources/Options/Array.swift
new file mode 100644
index 0000000..e192aa1
--- /dev/null
+++ b/Sources/Options/Array.swift
@@ -0,0 +1,50 @@
+//
+// Array.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+// swiftlint:disable:next line_length
+@available(*, deprecated, renamed: "MappedValueGenericRepresented", message: "Use MappedValueGenericRepresented instead.")
+public protocol MappedValueCollectionRepresented: MappedValueGenericRepresented
+ where MappedValueType: Sequence {}
+
+extension Array: MappedValues where Element: Equatable {
+ public func key(value: Element) throws -> Int {
+ guard let index = firstIndex(of: value) else {
+ throw MappedValueRepresentableError.valueNotFound
+ }
+
+ return index
+ }
+
+ public func value(key: Int) throws -> Element {
+ guard key < count, key >= 0 else {
+ throw MappedValueRepresentableError.valueNotFound
+ }
+ return self[key]
+ }
+}
diff --git a/Sources/Options/Dictionary.swift b/Sources/Options/Dictionary.swift
new file mode 100644
index 0000000..79e2b8e
--- /dev/null
+++ b/Sources/Options/Dictionary.swift
@@ -0,0 +1,51 @@
+//
+// Dictionary.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+// swiftlint:disable:next line_length
+@available(*, deprecated, renamed: "MappedValueGenericRepresented", message: "Use MappedValueGenericRepresented instead.")
+public protocol MappedValueDictionaryRepresented: MappedValueGenericRepresented
+ where MappedValueType == [Int: MappedType] {}
+
+extension Dictionary: MappedValues where Key == Int, Value: Equatable {
+ public func key(value: Value) throws -> Int {
+ let pair = first { $0.value == value }
+ guard let key = pair?.key else {
+ throw MappedValueRepresentableError.valueNotFound
+ }
+
+ return key
+ }
+
+ public func value(key: Int) throws -> Value {
+ guard let value = self[key] else {
+ throw MappedValueRepresentableError.valueNotFound
+ }
+ return value
+ }
+}
diff --git a/Sources/Options/EnumSet.swift b/Sources/Options/EnumSet.swift
index af24a03..69a4b3b 100644
--- a/Sources/Options/EnumSet.swift
+++ b/Sources/Options/EnumSet.swift
@@ -1,5 +1,5 @@
/// Generic struct for using Enums with RawValue type of Int as an Optionset
-public struct EnumSet: OptionSet
+public struct EnumSet: OptionSet, Sendable
where EnumType.RawValue == Int {
public typealias RawValue = EnumType.RawValue
@@ -15,7 +15,7 @@ public struct EnumSet: OptionSet
/// Creates the EnumSet based on the values in the array.
/// - Parameter values: Array of enum values.
public init(values: [EnumType]) {
- let set = Set(values.map { $0.rawValue })
+ let set = Set(values.map(\.rawValue))
rawValue = Self.cumulativeValue(basedOnRawValues: set)
}
@@ -50,26 +50,52 @@ extension EnumSet where EnumType: CaseIterable {
}
}
-extension EnumSet: Codable
- where EnumType: MappedValueRepresentable, EnumType.MappedType: Codable {
- /// Decodes the EnumSet based on an Array of MappedTypes.
- /// - Parameter decoder: Decoder which contains info as an array of MappedTypes.
- public init(from decoder: Decoder) throws {
- let container = try decoder.singleValueContainer()
- let values = try container.decode([EnumType.MappedType].self)
- let rawValues = try values.map(EnumType.rawValue(basedOn:))
- let set = Set(rawValues)
- rawValue = Self.cumulativeValue(basedOnRawValues: set)
+#if swift(>=5.9)
+ extension EnumSet: Codable
+ where EnumType: MappedValueRepresentable, EnumType.MappedType: Codable {
+ /// Decodes the EnumSet based on an Array of MappedTypes.
+ /// - Parameter decoder: Decoder which contains info as an array of MappedTypes.
+ public init(from decoder: any Decoder) throws {
+ let container = try decoder.singleValueContainer()
+ let values = try container.decode([EnumType.MappedType].self)
+ let rawValues = try values.map(EnumType.rawValue(basedOn:))
+ let set = Set(rawValues)
+ rawValue = Self.cumulativeValue(basedOnRawValues: set)
+ }
+
+ /// Encodes the EnumSet based on an Array of MappedTypes.
+ /// - Parameter encoder: Encoder which will contain info as an array of MappedTypes.
+ public func encode(to encoder: any Encoder) throws {
+ var container = encoder.singleValueContainer()
+ let values = Self.enums(basedOnRawValue: rawValue)
+ let mappedValues = try values
+ .map(\.rawValue)
+ .map(EnumType.mappedValue(basedOn:))
+ try container.encode(mappedValues)
+ }
}
+#else
+ extension EnumSet: Codable
+ where EnumType: MappedValueRepresentable, EnumType.MappedType: Codable {
+ /// Decodes the EnumSet based on an Array of MappedTypes.
+ /// - Parameter decoder: Decoder which contains info as an array of MappedTypes.
+ public init(from decoder: Decoder) throws {
+ let container = try decoder.singleValueContainer()
+ let values = try container.decode([EnumType.MappedType].self)
+ let rawValues = try values.map(EnumType.rawValue(basedOn:))
+ let set = Set(rawValues)
+ rawValue = Self.cumulativeValue(basedOnRawValues: set)
+ }
- /// Encodes the EnumSet based on an Array of MappedTypes.
- /// - Parameter encoder: Encoder which will contain info as an array of MappedTypes.
- public func encode(to encoder: Encoder) throws {
- var container = encoder.singleValueContainer()
- let values = Self.enums(basedOnRawValue: rawValue)
- let mappedValues = try values
- .map { $0.rawValue }
- .map(EnumType.mappedValue(basedOn:))
- try container.encode(mappedValues)
+ /// Encodes the EnumSet based on an Array of MappedTypes.
+ /// - Parameter encoder: Encoder which will contain info as an array of MappedTypes.
+ public func encode(to encoder: Encoder) throws {
+ var container = encoder.singleValueContainer()
+ let values = Self.enums(basedOnRawValue: rawValue)
+ let mappedValues = try values
+ .map(\.rawValue)
+ .map(EnumType.mappedValue(basedOn:))
+ try container.encode(mappedValues)
+ }
}
-}
+#endif
diff --git a/Sources/Options/Macro.swift b/Sources/Options/Macro.swift
new file mode 100644
index 0000000..e120423
--- /dev/null
+++ b/Sources/Options/Macro.swift
@@ -0,0 +1,40 @@
+//
+// Macro.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+import Foundation
+
+#if swift(>=5.10)
+ @attached(
+ extension,
+ conformances: MappedValueRepresentable, MappedValueGenericRepresented,
+ names: named(MappedType), named(mappedValues)
+ )
+ @attached(peer, names: suffixed(Set))
+ public macro Options() = #externalMacro(module: "OptionsMacros", type: "OptionsMacro")
+#endif
diff --git a/Sources/Options/MappedEnum.swift b/Sources/Options/MappedEnum.swift
index 58eba20..1e651d5 100644
--- a/Sources/Options/MappedEnum.swift
+++ b/Sources/Options/MappedEnum.swift
@@ -1,5 +1,5 @@
/// A generic struct for enumerations which allow for additional values attached.
-public struct MappedEnum: Codable
+public struct MappedEnum: Codable, Sendable
where EnumType.MappedType: Codable {
/// Base Enumeraion value.
public let value: EnumType
@@ -9,24 +9,50 @@ public struct MappedEnum: Codable
public init(value: EnumType) {
self.value = value
}
+}
- /// Decodes the value based on the mapped value.
- /// - Parameter decoder: Decoder.
- public init(from decoder: Decoder) throws {
- let container = try decoder.singleValueContainer()
- let label = try container.decode(EnumType.MappedType.self)
- let rawValue = try EnumType.rawValue(basedOn: label)
- guard let value = EnumType(rawValue: rawValue) else {
- preconditionFailure("Invalid Raw Value.")
+#if swift(>=5.9)
+ extension MappedEnum {
+ /// Decodes the value based on the mapped value.
+ /// - Parameter decoder: Decoder.
+ public init(from decoder: any Decoder) throws {
+ let container = try decoder.singleValueContainer()
+ let label = try container.decode(EnumType.MappedType.self)
+ let rawValue = try EnumType.rawValue(basedOn: label)
+ guard let value = EnumType(rawValue: rawValue) else {
+ preconditionFailure("Invalid Raw Value.")
+ }
+ self.value = value
+ }
+
+ /// Encodes the value based on the mapped value.
+ /// - Parameter encoder: Encoder.
+ public func encode(to encoder: any Encoder) throws {
+ let string = try EnumType.mappedValue(basedOn: value.rawValue)
+ var container = encoder.singleValueContainer()
+ try container.encode(string)
}
- self.value = value
}
+#else
+ extension MappedEnum {
+ /// Decodes the value based on the mapped value.
+ /// - Parameter decoder: Decoder.
+ public init(from decoder: Decoder) throws {
+ let container = try decoder.singleValueContainer()
+ let label = try container.decode(EnumType.MappedType.self)
+ let rawValue = try EnumType.rawValue(basedOn: label)
+ guard let value = EnumType(rawValue: rawValue) else {
+ preconditionFailure("Invalid Raw Value.")
+ }
+ self.value = value
+ }
- /// Encodes the value based on the mapped value.
- /// - Parameter encoder: Encoder.
- public func encode(to encoder: Encoder) throws {
- let string = try EnumType.mappedValue(basedOn: value.rawValue)
- var container = encoder.singleValueContainer()
- try container.encode(string)
+ /// Encodes the value based on the mapped value.
+ /// - Parameter encoder: Encoder.
+ public func encode(to encoder: Encoder) throws {
+ let string = try EnumType.mappedValue(basedOn: value.rawValue)
+ var container = encoder.singleValueContainer()
+ try container.encode(string)
+ }
}
-}
+#endif
diff --git a/Sources/Options/MappedValueCollectionRepresented.swift b/Sources/Options/MappedValueCollectionRepresented.swift
deleted file mode 100644
index dc576fe..0000000
--- a/Sources/Options/MappedValueCollectionRepresented.swift
+++ /dev/null
@@ -1,38 +0,0 @@
-/// Protocol which simplifies mapped value by using an ordered Array of values.
-public protocol MappedValueCollectionRepresented: MappedValueRepresentable
- where RawValue == Int, MappedType: Equatable {
- /// An array of the mapped values which lines up with each case.
- static var mappedValues: [MappedType] { get }
-}
-
-public extension MappedValueCollectionRepresented {
- /// Gets the raw value based on the MappedType by finding the index of the mapped value.
- /// - Parameter value: MappedType value.
- /// - Throws: `MappedValueCollectionRepresentedError.valueNotFound`
- /// If the value was not found in the array
- /// - Returns:
- /// The raw value of the enumeration
- /// based on the index the MappedType value was found at.
- static func rawValue(basedOn value: MappedType) throws -> RawValue {
- guard let index = mappedValues.firstIndex(of: value) else {
- throw MappedValueRepresentableError.valueNotFound
- }
-
- return index
- }
-
- /// Gets the mapped value based on the rawValue
- /// by access the array at the raw value subscript.
- /// - Parameter rawValue: The raw value of the enumeration
- /// which pretains to its index in the `mappedValues` Array.
- /// - Throws: `MappedValueCollectionRepresentedError.valueNotFound`
- /// if the raw value (i.e. index) is outside the range of the `mappedValues` array.
- /// - Returns:
- /// The Mapped Type value based on the value in the array at the raw value index.
- static func mappedValue(basedOn rawValue: RawValue) throws -> MappedType {
- guard rawValue < mappedValues.count, rawValue >= 0 else {
- throw MappedValueRepresentableError.valueNotFound
- }
- return Self.mappedValues[rawValue]
- }
-}
diff --git a/Sources/Options/MappedValueDictionaryRepresented.swift b/Sources/Options/MappedValueDictionaryRepresented.swift
deleted file mode 100644
index cc3a551..0000000
--- a/Sources/Options/MappedValueDictionaryRepresented.swift
+++ /dev/null
@@ -1,39 +0,0 @@
-/// Protocol which simplifies mapped value by using a dictionary.
-public protocol MappedValueDictionaryRepresented: MappedValueRepresentable
- where RawValue == Int, MappedType: Equatable {
- /// An dictionary of the mapped values.
- static var mappedValues: [Int: MappedType] { get }
-}
-
-public extension MappedValueDictionaryRepresented {
- /// Gets the raw value based on the MappedType by finding the key of the mapped value.
- /// - Parameter value: MappedType value.
- /// - Throws: `MappedValueCollectionRepresentedError.valueNotFound`
- /// If the value was not found in the dictionary
- /// - Returns:
- /// The raw value of the enumeration
- /// based on the key the MappedType value.
- static func rawValue(basedOn value: MappedType) throws -> RawValue {
- let pair = mappedValues.first { $0.value == value }
- guard let key = pair?.key else {
- throw MappedValueRepresentableError.valueNotFound
- }
-
- return key
- }
-
- /// Gets the mapped value based on the rawValue
- /// by access the dictionary at the raw value key.
- /// - Parameter rawValue: The raw value of the enumeration
- /// which pretains to its index in the `mappedValues` Array.
- /// - Throws: `MappedValueCollectionRepresentedError.valueNotFound`
- /// if the raw value (i.e. key) is not in the dictionary.
- /// - Returns:
- /// The Mapped Type value based on the raw value key.
- static func mappedValue(basedOn rawValue: RawValue) throws -> MappedType {
- guard let value = mappedValues[rawValue] else {
- throw MappedValueRepresentableError.valueNotFound
- }
- return value
- }
-}
diff --git a/Sources/Options/MappedValueGenericRepresented.swift b/Sources/Options/MappedValueGenericRepresented.swift
new file mode 100644
index 0000000..271510b
--- /dev/null
+++ b/Sources/Options/MappedValueGenericRepresented.swift
@@ -0,0 +1,61 @@
+//
+// MappedValueGenericRepresented.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+/// Protocol which simplifies ``MappedValueRepresentable``by using a ``MappedValues``.
+public protocol MappedValueGenericRepresented: MappedValueRepresentable
+ where RawValue == Int, MappedType: Equatable {
+ associatedtype MappedValueType: MappedValues
+ /// An array of the mapped values which lines up with each case.
+ static var mappedValues: MappedValueType { get }
+}
+
+extension MappedValueGenericRepresented {
+ /// Gets the raw value based on the MappedType by finding the index of the mapped value.
+ /// - Parameter value: MappedType value.
+ /// - Throws: `MappedValueCollectionRepresentedError.valueNotFound`
+ /// If the value was not found in the array
+ /// - Returns:
+ /// The raw value of the enumeration
+ /// based on the index the MappedType value was found at.
+ public static func rawValue(basedOn value: MappedType) throws -> RawValue {
+ try mappedValues.key(value: value)
+ }
+
+ /// Gets the mapped value based on the rawValue
+ /// by access the array at the raw value subscript.
+ /// - Parameter rawValue: The raw value of the enumeration
+ /// which pretains to its index in the `mappedValues` Array.
+ /// - Throws: `MappedValueCollectionRepresentedError.valueNotFound`
+ /// if the raw value (i.e. index) is outside the range of the `mappedValues` array.
+ /// - Returns:
+ /// The Mapped Type value based on the value in the array at the raw value index.
+ public static func mappedValue(basedOn rawValue: RawValue) throws -> MappedType {
+ try mappedValues.value(key: rawValue)
+ }
+}
diff --git a/Sources/Options/MappedValueRepresentable.swift b/Sources/Options/MappedValueRepresentable.swift
index 68d8929..415ca82 100644
--- a/Sources/Options/MappedValueRepresentable.swift
+++ b/Sources/Options/MappedValueRepresentable.swift
@@ -1,5 +1,34 @@
-public protocol MappedValueRepresentable: RawRepresentable, CaseIterable {
- associatedtype MappedType
+//
+// MappedValueRepresentable.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+public protocol MappedValueRepresentable: RawRepresentable, CaseIterable, Sendable {
+ associatedtype MappedType = String
/// Gets the raw value based on the MappedType.
/// - Parameter value: MappedType value.
/// - Returns: The raw value of the enumeration based on the `MappedType `value.
@@ -11,7 +40,7 @@ public protocol MappedValueRepresentable: RawRepresentable, CaseIterable {
static func mappedValue(basedOn rawValue: RawValue) throws -> MappedType
}
-public extension MappedValueRepresentable {
+extension MappedValueRepresentable {
/// Gets the mapped value of the enumeration.
/// - Parameter rawValue: The raw value of the enumeration
/// which pretains to its index in the `mappedValues` Array.
@@ -23,7 +52,7 @@ public extension MappedValueRepresentable {
/// Gets the mapped value of the enumeration.
/// - Returns: The `MappedType` value
- func mappedValue() throws -> MappedType {
+ public func mappedValue() throws -> MappedType {
try Self.mappedValue(basedOn: rawValue)
}
}
diff --git a/Sources/Options/MappedValueRepresentableError.swift b/Sources/Options/MappedValueRepresentableError.swift
index 86d00f9..3d1389f 100644
--- a/Sources/Options/MappedValueRepresentableError.swift
+++ b/Sources/Options/MappedValueRepresentableError.swift
@@ -1,7 +1,46 @@
+//
+// MappedValueRepresentableError.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
import Foundation
-/// An Error thrown when the `MappedType` value or `RawType` value
-/// are invalid for an `Enum`.
-public enum MappedValueRepresentableError: Error {
- case valueNotFound
-}
+// swiftlint:disable file_types_order
+#if swift(>=5.10)
+ /// An Error thrown when the `MappedType` value or `RawType` value
+ /// are invalid for an `Enum`.
+ public enum MappedValueRepresentableError: Error, Sendable {
+ case valueNotFound
+ }
+#else
+ /// An Error thrown when the `MappedType` value or `RawType` value
+ /// are invalid for an `Enum`.
+ public enum MappedValueRepresentableError: Error {
+ case valueNotFound
+ }
+#endif
+// swiftlint:enable file_types_order
diff --git a/Sources/Options/MappedValues.swift b/Sources/Options/MappedValues.swift
new file mode 100644
index 0000000..8d067eb
--- /dev/null
+++ b/Sources/Options/MappedValues.swift
@@ -0,0 +1,40 @@
+//
+// MappedValues.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+import Foundation
+
+/// Protocol which provides a method for ``MappedValueGenericRepresented`` to pull values.
+public protocol MappedValues {
+ /// Raw Value Type
+ associatedtype Value: Equatable
+ /// get the key vased on the value.
+ func key(value: Value) throws -> Int
+ /// get the value based on the key/index.
+ func value(key: Int) throws -> Value
+}
diff --git a/Sources/OptionsMacros/Extensions/Array.swift b/Sources/OptionsMacros/Extensions/Array.swift
new file mode 100644
index 0000000..78275fe
--- /dev/null
+++ b/Sources/OptionsMacros/Extensions/Array.swift
@@ -0,0 +1,42 @@
+//
+// Array.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+import Foundation
+
+extension Array {
+ internal init?(keyValues: KeyValues) where Element == String {
+ self.init()
+ for key in 0 ..< keyValues.count {
+ guard let value = keyValues.get(key) else {
+ return nil
+ }
+ append(value)
+ }
+ }
+}
diff --git a/Sources/OptionsMacros/Extensions/ArrayExprSyntax.swift b/Sources/OptionsMacros/Extensions/ArrayExprSyntax.swift
new file mode 100644
index 0000000..2cab374
--- /dev/null
+++ b/Sources/OptionsMacros/Extensions/ArrayExprSyntax.swift
@@ -0,0 +1,43 @@
+//
+// ArrayExprSyntax.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+import SwiftSyntax
+
+extension ArrayExprSyntax {
+ internal init(
+ from items: some Collection,
+ _ closure: @escaping @Sendable (T) -> some ExprSyntaxProtocol
+ ) {
+ let values = items.map(closure).map { ArrayElementSyntax(expression: $0) }
+ let arrayElement = ArrayElementListSyntax {
+ .init(values)
+ }
+ self.init(elements: arrayElement)
+ }
+}
diff --git a/Sources/OptionsMacros/Extensions/DeclModifierListSyntax.swift b/Sources/OptionsMacros/Extensions/DeclModifierListSyntax.swift
new file mode 100644
index 0000000..c155633
--- /dev/null
+++ b/Sources/OptionsMacros/Extensions/DeclModifierListSyntax.swift
@@ -0,0 +1,42 @@
+//
+// DeclModifierListSyntax.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+import SwiftSyntax
+
+extension DeclModifierListSyntax {
+ internal init(keywordModifier: Keyword?) {
+ if let keywordModifier {
+ self.init {
+ DeclModifierSyntax(name: .keyword(keywordModifier))
+ }
+ } else {
+ self.init([])
+ }
+ }
+}
diff --git a/Sources/OptionsMacros/Extensions/DeclModifierSyntax.swift b/Sources/OptionsMacros/Extensions/DeclModifierSyntax.swift
new file mode 100644
index 0000000..f4981a4
--- /dev/null
+++ b/Sources/OptionsMacros/Extensions/DeclModifierSyntax.swift
@@ -0,0 +1,39 @@
+//
+// DeclModifierSyntax.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+import SwiftSyntax
+
+extension DeclModifierSyntax {
+ internal var isNeededAccessLevelModifier: Bool {
+ switch name.tokenKind {
+ case .keyword(.public): return true
+ default: return false
+ }
+ }
+}
diff --git a/Sources/OptionsMacros/Extensions/DictionaryElementSyntax.swift b/Sources/OptionsMacros/Extensions/DictionaryElementSyntax.swift
new file mode 100644
index 0000000..b719a24
--- /dev/null
+++ b/Sources/OptionsMacros/Extensions/DictionaryElementSyntax.swift
@@ -0,0 +1,47 @@
+//
+// DictionaryElementSyntax.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+import SwiftSyntax
+
+extension DictionaryElementSyntax {
+ internal init(pair: (key: Int, value: String)) {
+ self.init(key: pair.key, value: pair.value)
+ }
+
+ internal init(key: Int, value: String) {
+ self.init(
+ key: IntegerLiteralExprSyntax(integerLiteral: key),
+ value: StringLiteralExprSyntax(
+ openingQuote: .stringQuoteToken(),
+ segments: .init([.stringSegment(.init(content: .stringSegment(value)))]),
+ closingQuote: .stringQuoteToken()
+ )
+ )
+ }
+}
diff --git a/Sources/OptionsMacros/Extensions/DictionaryExprSyntax.swift b/Sources/OptionsMacros/Extensions/DictionaryExprSyntax.swift
new file mode 100644
index 0000000..d21549b
--- /dev/null
+++ b/Sources/OptionsMacros/Extensions/DictionaryExprSyntax.swift
@@ -0,0 +1,41 @@
+//
+// DictionaryExprSyntax.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+import SwiftSyntax
+
+extension DictionaryExprSyntax {
+ internal init(keyValues: KeyValues) {
+ let dictionaryElements = keyValues.dictionary.map(DictionaryElementSyntax.init(pair:))
+
+ let list = DictionaryElementListSyntax {
+ .init(dictionaryElements)
+ }
+ self.init(content: .elements(list))
+ }
+}
diff --git a/Sources/OptionsMacros/Extensions/EnumDeclSyntax.swift b/Sources/OptionsMacros/Extensions/EnumDeclSyntax.swift
new file mode 100644
index 0000000..07035df
--- /dev/null
+++ b/Sources/OptionsMacros/Extensions/EnumDeclSyntax.swift
@@ -0,0 +1,42 @@
+//
+// EnumDeclSyntax.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+import SwiftSyntax
+
+extension EnumDeclSyntax {
+ internal var caseElements: [EnumCaseElementSyntax] {
+ memberBlock.members.flatMap { member in
+ guard let caseDecl = member.decl.as(EnumCaseDeclSyntax.self) else {
+ return [EnumCaseElementSyntax]()
+ }
+
+ return Array(caseDecl.elements)
+ }
+ }
+}
diff --git a/Sources/OptionsMacros/Extensions/ExtensionDeclSyntax.swift b/Sources/OptionsMacros/Extensions/ExtensionDeclSyntax.swift
new file mode 100644
index 0000000..cf1eb6e
--- /dev/null
+++ b/Sources/OptionsMacros/Extensions/ExtensionDeclSyntax.swift
@@ -0,0 +1,57 @@
+//
+// ExtensionDeclSyntax.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+import SwiftSyntax
+
+extension ExtensionDeclSyntax {
+ internal init(
+ enumDecl: EnumDeclSyntax,
+ conformingTo protocols: [SwiftSyntax.TypeSyntax]
+ ) throws {
+ let typeName = enumDecl.name
+
+ let access = enumDecl.modifiers.first(where: \.isNeededAccessLevelModifier)
+
+ let mappedValues = try VariableDeclSyntax.mappedValuesDeclarationForCases(
+ enumDecl.caseElements
+ )
+
+ self.init(
+ modifiers: DeclModifierListSyntax([access].compactMap { $0 }),
+ extendedType: IdentifierTypeSyntax(name: typeName),
+ inheritanceClause: InheritanceClauseSyntax(protocols: protocols),
+ memberBlock: MemberBlockSyntax(
+ members: MemberBlockItemListSyntax {
+ TypeAliasDeclSyntax(name: "MappedType", for: "String")
+ mappedValues
+ }
+ )
+ )
+ }
+}
diff --git a/Sources/OptionsMacros/Extensions/InheritanceClauseSyntax.swift b/Sources/OptionsMacros/Extensions/InheritanceClauseSyntax.swift
new file mode 100644
index 0000000..be7dc57
--- /dev/null
+++ b/Sources/OptionsMacros/Extensions/InheritanceClauseSyntax.swift
@@ -0,0 +1,44 @@
+//
+// InheritanceClauseSyntax.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+import SwiftSyntax
+
+extension InheritanceClauseSyntax {
+ internal init(protocols: [SwiftSyntax.TypeSyntax]) {
+ self.init(
+ inheritedTypes: .init {
+ .init(
+ protocols.map { typeSyntax in
+ InheritedTypeSyntax(type: typeSyntax)
+ }
+ )
+ }
+ )
+ }
+}
diff --git a/Sources/OptionsMacros/Extensions/KeyValues.swift b/Sources/OptionsMacros/Extensions/KeyValues.swift
new file mode 100644
index 0000000..7800a73
--- /dev/null
+++ b/Sources/OptionsMacros/Extensions/KeyValues.swift
@@ -0,0 +1,70 @@
+//
+// KeyValues.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+import SwiftSyntax
+
+internal struct KeyValues {
+ internal private(set) var lastKey: Int?
+ internal private(set) var dictionary = [Int: String]()
+
+ internal var count: Int {
+ dictionary.count
+ }
+
+ internal var nextKey: Int {
+ (lastKey ?? -1) + 1
+ }
+
+ internal mutating func append(value: String, withKey key: Int? = nil) throws {
+ let key = key ?? nextKey
+ guard dictionary[key] == nil else {
+ throw InvalidDeclError.rawValue(key)
+ }
+ lastKey = key
+ dictionary[key] = value
+ }
+
+ internal func get(_ key: Int) -> String? {
+ dictionary[key]
+ }
+}
+
+extension KeyValues {
+ internal init(caseElements: [EnumCaseElementSyntax]) throws {
+ self.init()
+ for caseElement in caseElements {
+ let intText = caseElement.rawValue?.value
+ .as(IntegerLiteralExprSyntax.self)?.literal.text
+ let key = intText.flatMap { Int($0) }
+ let value =
+ caseElement.name.trimmed.text
+ try append(value: value, withKey: key)
+ }
+ }
+}
diff --git a/Sources/OptionsMacros/Extensions/TypeAliasDeclSyntax.swift b/Sources/OptionsMacros/Extensions/TypeAliasDeclSyntax.swift
new file mode 100644
index 0000000..b682f69
--- /dev/null
+++ b/Sources/OptionsMacros/Extensions/TypeAliasDeclSyntax.swift
@@ -0,0 +1,39 @@
+//
+// TypeAliasDeclSyntax.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+import SwiftSyntax
+
+extension TypeAliasDeclSyntax {
+ internal init(name: TokenSyntax, for initializerTypeName: TokenSyntax) {
+ self.init(
+ name: name,
+ initializer: .init(value: IdentifierTypeSyntax(name: initializerTypeName))
+ )
+ }
+}
diff --git a/Sources/OptionsMacros/Extensions/VariableDeclSyntax.swift b/Sources/OptionsMacros/Extensions/VariableDeclSyntax.swift
new file mode 100644
index 0000000..48dd371
--- /dev/null
+++ b/Sources/OptionsMacros/Extensions/VariableDeclSyntax.swift
@@ -0,0 +1,81 @@
+//
+// VariableDeclSyntax.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+import SwiftSyntax
+
+extension VariableDeclSyntax {
+ internal init(
+ keywordModifier: Keyword?,
+ bindingKeyword: Keyword,
+ variableName: String,
+ initializerExpression: (some ExprSyntaxProtocol)?
+ ) {
+ let modifiers = DeclModifierListSyntax(keywordModifier: keywordModifier)
+
+ let initializer: InitializerClauseSyntax? =
+ initializerExpression.map { .init(value: $0) }
+
+ self.init(
+ modifiers: modifiers,
+ bindingSpecifier: .keyword(bindingKeyword),
+ bindings: .init {
+ PatternBindingSyntax(
+ pattern: IdentifierPatternSyntax(identifier: .identifier(variableName)),
+ initializer: initializer
+ )
+ }
+ )
+ }
+
+ internal static func initializerExpression(
+ from caseElements: [EnumCaseElementSyntax]
+ ) throws -> any ExprSyntaxProtocol {
+ let keyValues = try KeyValues(caseElements: caseElements)
+ if let array = Array(keyValues: keyValues) {
+ return ArrayExprSyntax(from: array) { value in
+ StringLiteralExprSyntax(content: value)
+ }
+ } else {
+ return DictionaryExprSyntax(keyValues: keyValues)
+ }
+ }
+
+ internal static func mappedValuesDeclarationForCases(
+ _ caseElements: [EnumCaseElementSyntax]
+ ) throws -> VariableDeclSyntax {
+ let arrayExpression = try Self.initializerExpression(from: caseElements)
+
+ return VariableDeclSyntax(
+ keywordModifier: .static,
+ bindingKeyword: .let,
+ variableName: "mappedValues",
+ initializerExpression: arrayExpression
+ )
+ }
+}
diff --git a/Sources/OptionsMacros/InvalidDeclError.swift b/Sources/OptionsMacros/InvalidDeclError.swift
new file mode 100644
index 0000000..ea31645
--- /dev/null
+++ b/Sources/OptionsMacros/InvalidDeclError.swift
@@ -0,0 +1,35 @@
+//
+// InvalidDeclError.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+@preconcurrency import SwiftSyntax
+
+internal enum InvalidDeclError: Error, Sendable {
+ case kind(SyntaxKind)
+ case rawValue(Int)
+}
diff --git a/Sources/OptionsMacros/MacrosPlugin.swift b/Sources/OptionsMacros/MacrosPlugin.swift
new file mode 100644
index 0000000..1bc8833
--- /dev/null
+++ b/Sources/OptionsMacros/MacrosPlugin.swift
@@ -0,0 +1,39 @@
+//
+// MacrosPlugin.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+import SwiftCompilerPlugin
+import SwiftSyntax
+import SwiftSyntaxMacros
+
+@main
+internal struct MacrosPlugin: CompilerPlugin {
+ internal let providingMacros: [any Macro.Type] = [
+ OptionsMacro.self
+ ]
+}
diff --git a/Sources/OptionsMacros/OptionsMacro.swift b/Sources/OptionsMacros/OptionsMacro.swift
new file mode 100644
index 0000000..8f93f5d
--- /dev/null
+++ b/Sources/OptionsMacros/OptionsMacro.swift
@@ -0,0 +1,69 @@
+//
+// OptionsMacro.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+import SwiftSyntax
+import SwiftSyntaxMacros
+
+public struct OptionsMacro: ExtensionMacro, PeerMacro {
+ public static func expansion(
+ of _: SwiftSyntax.AttributeSyntax,
+ providingPeersOf declaration: some SwiftSyntax.DeclSyntaxProtocol,
+ in _: some SwiftSyntaxMacros.MacroExpansionContext
+ ) throws -> [SwiftSyntax.DeclSyntax] {
+ guard let enumDecl = declaration.as(EnumDeclSyntax.self) else {
+ throw InvalidDeclError.kind(declaration.kind)
+ }
+ let typeName = enumDecl.name
+
+ let aliasName: TokenSyntax = "\(typeName.trimmed)Set"
+
+ let initializerName: TokenSyntax = "EnumSet<\(typeName)>"
+
+ return [
+ .init(TypeAliasDeclSyntax(name: aliasName, for: initializerName))
+ ]
+ }
+
+ public static func expansion(
+ of _: SwiftSyntax.AttributeSyntax,
+ attachedTo declaration: some SwiftSyntax.DeclGroupSyntax,
+ providingExtensionsOf _: some SwiftSyntax.TypeSyntaxProtocol,
+ conformingTo protocols: [SwiftSyntax.TypeSyntax],
+ in _: some SwiftSyntaxMacros.MacroExpansionContext
+ ) throws -> [SwiftSyntax.ExtensionDeclSyntax] {
+ guard let enumDecl = declaration.as(EnumDeclSyntax.self) else {
+ throw InvalidDeclError.kind(declaration.kind)
+ }
+
+ let extensionDecl = try ExtensionDeclSyntax(
+ enumDecl: enumDecl, conformingTo: protocols
+ )
+ return [extensionDecl]
+ }
+}
diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift
deleted file mode 100644
index 14cf610..0000000
--- a/Tests/LinuxMain.swift
+++ /dev/null
@@ -1,8 +0,0 @@
-import XCTest
-
-import OptionsTests
-
-var tests = [XCTestCaseEntry]()
-tests += OptionsTests.__allTests()
-
-XCTMain(tests)
diff --git a/Tests/OptionsTests/EnumSetTests.swift b/Tests/OptionsTests/EnumSetTests.swift
index d0ee471..c741779 100644
--- a/Tests/OptionsTests/EnumSetTests.swift
+++ b/Tests/OptionsTests/EnumSetTests.swift
@@ -1,61 +1,88 @@
-#if canImport(XCTest)
- @testable import Options
- import XCTest
-
- internal final class EnumSetTests: XCTestCase {
- private static let text = "[\"a\",\"b\",\"c\"]"
-
- internal func testDecoder() {
- // swiftlint:disable:next force_unwrapping
- let data = Self.text.data(using: .utf8)!
- let decoder = JSONDecoder()
- let actual: EnumSet
- do {
- actual = try decoder.decode(EnumSet.self, from: data)
- } catch {
- XCTAssertNil(error)
- return
- }
- XCTAssertEqual(actual.rawValue, 7)
- }
+//
+// EnumSetTests.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
- internal func testEncoder() {
- let enumSet = EnumSet(values: [.a, .b, .c])
- let encoder = JSONEncoder()
- let data: Data
- do {
- data = try encoder.encode(enumSet)
- } catch {
- XCTAssertNil(error)
- return
- }
-
- let dataText = String(bytes: data, encoding: .utf8)
-
- guard let text = dataText else {
- XCTAssertNotNil(dataText)
- return
- }
-
- XCTAssertEqual(text, Self.text)
- }
+@testable import Options
+import XCTest
+
+internal final class EnumSetTests: XCTestCase {
+ private static let text = "[\"a\",\"b\",\"c\"]"
- internal func testInitValue() {
- let set = EnumSet(rawValue: 7)
- XCTAssertEqual(set.rawValue, 7)
+ internal func testDecoder() {
+ // swiftlint:disable:next force_unwrapping
+ let data = Self.text.data(using: .utf8)!
+ let decoder = JSONDecoder()
+ let actual: EnumSet
+ do {
+ actual = try decoder.decode(EnumSet.self, from: data)
+ } catch {
+ XCTAssertNil(error)
+ return
}
+ XCTAssertEqual(actual.rawValue, 7)
+ }
- internal func testInitValues() {
- let values: [MockCollectionEnum] = [.a, .b, .c]
- let set = EnumSet(values: values)
- XCTAssertEqual(set.rawValue, 7)
+ internal func testEncoder() {
+ let enumSet = EnumSet(values: [.a, .b, .c])
+ let encoder = JSONEncoder()
+ let data: Data
+ do {
+ data = try encoder.encode(enumSet)
+ } catch {
+ XCTAssertNil(error)
+ return
}
- internal func testArray() {
- let expected: [MockCollectionEnum] = [.b, .d]
- let enumSet = EnumSet(values: expected)
- let actual = enumSet.array()
- XCTAssertEqual(actual, expected)
+ let dataText = String(bytes: data, encoding: .utf8)
+
+ guard let text = dataText else {
+ XCTAssertNotNil(dataText)
+ return
}
+
+ XCTAssertEqual(text, Self.text)
+ }
+
+ internal func testInitValue() {
+ let set = EnumSet(rawValue: 7)
+ XCTAssertEqual(set.rawValue, 7)
+ }
+
+ internal func testInitValues() {
+ let values: [MockCollectionEnum] = [.a, .b, .c]
+ let set = EnumSet(values: values)
+ XCTAssertEqual(set.rawValue, 7)
+ }
+
+ internal func testArray() {
+ let expected: [MockCollectionEnum] = [.b, .d]
+ let enumSet = EnumSet(values: expected)
+ let actual = enumSet.array()
+ XCTAssertEqual(actual, expected)
}
-#endif
+}
diff --git a/Tests/OptionsTests/MappedEnumTests.swift b/Tests/OptionsTests/MappedEnumTests.swift
index 84e0806..1e19650 100644
--- a/Tests/OptionsTests/MappedEnumTests.swift
+++ b/Tests/OptionsTests/MappedEnumTests.swift
@@ -1,43 +1,69 @@
-#if canImport(XCTest)
- @testable import Options
- import XCTest
+//
+// MappedEnumTests.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
- internal final class MappedEnumTests: XCTestCase {
- private static let text = "\"a\""
- internal func testDecoder() throws {
- // swiftlint:disable:next force_unwrapping
- let data = Self.text.data(using: .utf8)!
- let decoder = JSONDecoder()
- let actual: MappedEnum
- do {
- actual = try decoder.decode(MappedEnum.self, from: data)
- } catch {
- XCTAssertNil(error)
- return
- }
- XCTAssertEqual(actual.value, .a)
- }
+@testable import Options
+import XCTest
- internal func testEncoder() throws {
- let encoder = JSONEncoder()
- let describedEnum: MappedEnum = .init(value: .a)
- let data: Data
- do {
- data = try encoder.encode(describedEnum)
- } catch {
- XCTAssertNil(error)
- return
- }
+internal final class MappedEnumTests: XCTestCase {
+ private static let text = "\"a\""
+ internal func testDecoder() throws {
+ // swiftlint:disable:next force_unwrapping
+ let data = Self.text.data(using: .utf8)!
+ let decoder = JSONDecoder()
+ let actual: MappedEnum
+ do {
+ actual = try decoder.decode(MappedEnum.self, from: data)
+ } catch {
+ XCTAssertNil(error)
+ return
+ }
+ XCTAssertEqual(actual.value, .a)
+ }
- let dataText = String(bytes: data, encoding: .utf8)
+ internal func testEncoder() throws {
+ let encoder = JSONEncoder()
+ let describedEnum: MappedEnum = .init(value: .a)
+ let data: Data
+ do {
+ data = try encoder.encode(describedEnum)
+ } catch {
+ XCTAssertNil(error)
+ return
+ }
- guard let text = dataText else {
- XCTAssertNotNil(dataText)
- return
- }
+ let dataText = String(bytes: data, encoding: .utf8)
- XCTAssertEqual(text, Self.text)
+ guard let text = dataText else {
+ XCTAssertNotNil(dataText)
+ return
}
- }
-#endif
+ XCTAssertEqual(text, Self.text)
+ }
+}
diff --git a/Tests/OptionsTests/MappedValueCollectionRepresentedTests.swift b/Tests/OptionsTests/MappedValueCollectionRepresentedTests.swift
index 5176814..8719c74 100644
--- a/Tests/OptionsTests/MappedValueCollectionRepresentedTests.swift
+++ b/Tests/OptionsTests/MappedValueCollectionRepresentedTests.swift
@@ -1,51 +1,77 @@
-#if canImport(XCTest)
- @testable import Options
- import XCTest
+//
+// MappedValueCollectionRepresentedTests.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
- internal final class MappedValueCollectionRepresentedTests: XCTestCase {
- internal func testRawValue() {
- try XCTAssertEqual(MockCollectionEnum.rawValue(basedOn: "a"), 0)
- try XCTAssertEqual(MockCollectionEnum.rawValue(basedOn: "b"), 1)
- try XCTAssertEqual(MockCollectionEnum.rawValue(basedOn: "c"), 2)
- try XCTAssertEqual(MockCollectionEnum.rawValue(basedOn: "d"), 3)
- }
+@testable import Options
+import XCTest
- internal func testString() {
- try XCTAssertEqual(MockCollectionEnum.mappedValue(basedOn: 0), "a")
- try XCTAssertEqual(MockCollectionEnum.mappedValue(basedOn: 1), "b")
- try XCTAssertEqual(MockCollectionEnum.mappedValue(basedOn: 2), "c")
- try XCTAssertEqual(MockCollectionEnum.mappedValue(basedOn: 3), "d")
- }
+internal final class MappedValueCollectionRepresentedTests: XCTestCase {
+ internal func testRawValue() {
+ try XCTAssertEqual(MockCollectionEnum.rawValue(basedOn: "a"), 0)
+ try XCTAssertEqual(MockCollectionEnum.rawValue(basedOn: "b"), 1)
+ try XCTAssertEqual(MockCollectionEnum.rawValue(basedOn: "c"), 2)
+ try XCTAssertEqual(MockCollectionEnum.rawValue(basedOn: "d"), 3)
+ }
- internal func testRawValueFailure() {
- let caughtError: MappedValueRepresentableError?
- do {
- _ = try MockCollectionEnum.rawValue(basedOn: "e")
- caughtError = nil
- } catch let error as MappedValueRepresentableError {
- caughtError = error
- } catch {
- XCTAssertNil(error)
- caughtError = nil
- }
+ internal func testString() {
+ try XCTAssertEqual(MockCollectionEnum.mappedValue(basedOn: 0), "a")
+ try XCTAssertEqual(MockCollectionEnum.mappedValue(basedOn: 1), "b")
+ try XCTAssertEqual(MockCollectionEnum.mappedValue(basedOn: 2), "c")
+ try XCTAssertEqual(MockCollectionEnum.mappedValue(basedOn: 3), "d")
+ }
- XCTAssertEqual(caughtError, .valueNotFound)
+ internal func testRawValueFailure() {
+ let caughtError: MappedValueRepresentableError?
+ do {
+ _ = try MockCollectionEnum.rawValue(basedOn: "e")
+ caughtError = nil
+ } catch let error as MappedValueRepresentableError {
+ caughtError = error
+ } catch {
+ XCTAssertNil(error)
+ caughtError = nil
}
- internal func testStringFailure() {
- let caughtError: MappedValueRepresentableError?
- do {
- _ = try MockCollectionEnum.mappedValue(basedOn: .max)
- caughtError = nil
- } catch let error as MappedValueRepresentableError {
- caughtError = error
- } catch {
- XCTAssertNil(error)
- caughtError = nil
- }
+ XCTAssertEqual(caughtError, .valueNotFound)
+ }
- XCTAssertEqual(caughtError, .valueNotFound)
+ internal func testStringFailure() {
+ let caughtError: MappedValueRepresentableError?
+ do {
+ _ = try MockCollectionEnum.mappedValue(basedOn: .max)
+ caughtError = nil
+ } catch let error as MappedValueRepresentableError {
+ caughtError = error
+ } catch {
+ XCTAssertNil(error)
+ caughtError = nil
}
- }
-#endif
+ XCTAssertEqual(caughtError, .valueNotFound)
+ }
+}
diff --git a/Tests/OptionsTests/MappedValueDictionaryRepresentedTests.swift b/Tests/OptionsTests/MappedValueDictionaryRepresentedTests.swift
index fe97e0d..8aca268 100644
--- a/Tests/OptionsTests/MappedValueDictionaryRepresentedTests.swift
+++ b/Tests/OptionsTests/MappedValueDictionaryRepresentedTests.swift
@@ -1,51 +1,77 @@
-#if canImport(XCTest)
- @testable import Options
- import XCTest
+//
+// MappedValueDictionaryRepresentedTests.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
- internal final class MappedValueDictionaryRepresentedTests: XCTestCase {
- internal func testRawValue() {
- try XCTAssertEqual(MockDictionaryEnum.rawValue(basedOn: "a"), 2)
- try XCTAssertEqual(MockDictionaryEnum.rawValue(basedOn: "b"), 5)
- try XCTAssertEqual(MockDictionaryEnum.rawValue(basedOn: "c"), 6)
- try XCTAssertEqual(MockDictionaryEnum.rawValue(basedOn: "d"), 12)
- }
+@testable import Options
+import XCTest
- internal func testString() {
- try XCTAssertEqual(MockDictionaryEnum.mappedValue(basedOn: 2), "a")
- try XCTAssertEqual(MockDictionaryEnum.mappedValue(basedOn: 5), "b")
- try XCTAssertEqual(MockDictionaryEnum.mappedValue(basedOn: 6), "c")
- try XCTAssertEqual(MockDictionaryEnum.mappedValue(basedOn: 12), "d")
- }
+internal final class MappedValueDictionaryRepresentedTests: XCTestCase {
+ internal func testRawValue() {
+ try XCTAssertEqual(MockDictionaryEnum.rawValue(basedOn: "a"), 2)
+ try XCTAssertEqual(MockDictionaryEnum.rawValue(basedOn: "b"), 5)
+ try XCTAssertEqual(MockDictionaryEnum.rawValue(basedOn: "c"), 6)
+ try XCTAssertEqual(MockDictionaryEnum.rawValue(basedOn: "d"), 12)
+ }
- internal func testRawValueFailure() {
- let caughtError: MappedValueRepresentableError?
- do {
- _ = try MockDictionaryEnum.rawValue(basedOn: "e")
- caughtError = nil
- } catch let error as MappedValueRepresentableError {
- caughtError = error
- } catch {
- XCTAssertNil(error)
- caughtError = nil
- }
+ internal func testString() {
+ try XCTAssertEqual(MockDictionaryEnum.mappedValue(basedOn: 2), "a")
+ try XCTAssertEqual(MockDictionaryEnum.mappedValue(basedOn: 5), "b")
+ try XCTAssertEqual(MockDictionaryEnum.mappedValue(basedOn: 6), "c")
+ try XCTAssertEqual(MockDictionaryEnum.mappedValue(basedOn: 12), "d")
+ }
- XCTAssertEqual(caughtError, .valueNotFound)
+ internal func testRawValueFailure() {
+ let caughtError: MappedValueRepresentableError?
+ do {
+ _ = try MockDictionaryEnum.rawValue(basedOn: "e")
+ caughtError = nil
+ } catch let error as MappedValueRepresentableError {
+ caughtError = error
+ } catch {
+ XCTAssertNil(error)
+ caughtError = nil
}
- internal func testStringFailure() {
- let caughtError: MappedValueRepresentableError?
- do {
- _ = try MockDictionaryEnum.mappedValue(basedOn: 0)
- caughtError = nil
- } catch let error as MappedValueRepresentableError {
- caughtError = error
- } catch {
- XCTAssertNil(error)
- caughtError = nil
- }
+ XCTAssertEqual(caughtError, .valueNotFound)
+ }
- XCTAssertEqual(caughtError, .valueNotFound)
+ internal func testStringFailure() {
+ let caughtError: MappedValueRepresentableError?
+ do {
+ _ = try MockDictionaryEnum.mappedValue(basedOn: 0)
+ caughtError = nil
+ } catch let error as MappedValueRepresentableError {
+ caughtError = error
+ } catch {
+ XCTAssertNil(error)
+ caughtError = nil
}
- }
-#endif
+ XCTAssertEqual(caughtError, .valueNotFound)
+ }
+}
diff --git a/Tests/OptionsTests/MappedValueRepresentableTests.swift b/Tests/OptionsTests/MappedValueRepresentableTests.swift
index d3f5ca8..e400539 100644
--- a/Tests/OptionsTests/MappedValueRepresentableTests.swift
+++ b/Tests/OptionsTests/MappedValueRepresentableTests.swift
@@ -1,14 +1,40 @@
-#if canImport(XCTest)
- @testable import Options
- import XCTest
+//
+// MappedValueRepresentableTests.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
- internal final class MappedValueRepresentableTests: XCTestCase {
- internal func testStringValue() {
- try XCTAssertEqual(MockCollectionEnum.a.mappedValue(), "a")
- try XCTAssertEqual(MockCollectionEnum.b.mappedValue(), "b")
- try XCTAssertEqual(MockCollectionEnum.c.mappedValue(), "c")
- try XCTAssertEqual(MockCollectionEnum.d.mappedValue(), "d")
- }
- }
+@testable import Options
+import XCTest
-#endif
+internal final class MappedValueRepresentableTests: XCTestCase {
+ internal func testStringValue() {
+ try XCTAssertEqual(MockCollectionEnum.a.mappedValue(), "a")
+ try XCTAssertEqual(MockCollectionEnum.b.mappedValue(), "b")
+ try XCTAssertEqual(MockCollectionEnum.c.mappedValue(), "c")
+ try XCTAssertEqual(MockCollectionEnum.d.mappedValue(), "d")
+ }
+}
diff --git a/Tests/OptionsTests/Mocks/MockCollectionEnum.swift b/Tests/OptionsTests/Mocks/MockCollectionEnum.swift
index 93e3d80..c588f4f 100644
--- a/Tests/OptionsTests/Mocks/MockCollectionEnum.swift
+++ b/Tests/OptionsTests/Mocks/MockCollectionEnum.swift
@@ -1,17 +1,56 @@
-import Options
+//
+// MockCollectionEnum.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
-// swiftlint:disable identifier_name
+import Options
-internal enum MockCollectionEnum: Int, MappedValueCollectionRepresented {
- case a
- case b
- case c
- case d
- internal typealias MappedType = String
- internal static let mappedValues = [
- "a",
- "b",
- "c",
- "d"
- ]
-}
+#if swift(>=5.10)
+ // swiftlint:disable identifier_name
+ @Options
+ internal enum MockCollectionEnum: Int, Sendable {
+ case a
+ case b
+ case c
+ case d
+ }
+#else
+ // swiftlint:disable identifier_name
+ internal enum MockCollectionEnum: Int, MappedValueCollectionRepresented {
+ case a
+ case b
+ case c
+ case d
+ internal typealias MappedType = String
+ internal static let mappedValues = [
+ "a",
+ "b",
+ "c",
+ "d"
+ ]
+ }
+#endif
diff --git a/Tests/OptionsTests/Mocks/MockDictionaryEnum.swift b/Tests/OptionsTests/Mocks/MockDictionaryEnum.swift
index 7344654..77be088 100644
--- a/Tests/OptionsTests/Mocks/MockDictionaryEnum.swift
+++ b/Tests/OptionsTests/Mocks/MockDictionaryEnum.swift
@@ -1,17 +1,56 @@
-import Options
+//
+// MockDictionaryEnum.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
-// swiftlint:disable identifier_name
+import Options
-internal enum MockDictionaryEnum: Int, MappedValueDictionaryRepresented {
- case a = 2
- case b = 5
- case c = 6
- case d = 12
- internal typealias MappedType = String
- internal static var mappedValues = [
- 2: "a",
- 5: "b",
- 6: "c",
- 12: "d"
- ]
-}
+#if swift(>=5.10)
+ // swiftlint:disable identifier_name
+ @Options
+ internal enum MockDictionaryEnum: Int, Sendable {
+ case a = 2
+ case b = 5
+ case c = 6
+ case d = 12
+ }
+#else
+ // swiftlint:disable identifier_name
+ internal enum MockDictionaryEnum: Int, MappedValueDictionaryRepresented {
+ case a = 2
+ case b = 5
+ case c = 6
+ case d = 12
+ internal typealias MappedType = String
+ internal static var mappedValues = [
+ 2: "a",
+ 5: "b",
+ 6: "c",
+ 12: "d"
+ ]
+ }
+#endif
diff --git a/Tests/OptionsTests/Mocks/MockError.swift b/Tests/OptionsTests/Mocks/MockError.swift
index 47abd6f..1a7037b 100644
--- a/Tests/OptionsTests/Mocks/MockError.swift
+++ b/Tests/OptionsTests/Mocks/MockError.swift
@@ -1,3 +1,32 @@
+//
+// MockError.swift
+// SimulatorServices
+//
+// Created by Leo Dion.
+// Copyright © 2024 BrightDigit.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the “Software”), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
import Foundation
internal struct MockError: Error {
diff --git a/Tests/OptionsTests/XCTestManifests.swift b/Tests/OptionsTests/XCTestManifests.swift
deleted file mode 100644
index 31ea757..0000000
--- a/Tests/OptionsTests/XCTestManifests.swift
+++ /dev/null
@@ -1,69 +0,0 @@
-#if !canImport(ObjectiveC)
- import XCTest
-
- extension EnumSetTests {
- // DO NOT MODIFY: This is autogenerated, use:
- // `swift test --generate-linuxmain`
- // to regenerate.
- static let __allTests__EnumSetTests = [
- ("testArray", testArray),
- ("testDecoder", testDecoder),
- ("testEncoder", testEncoder),
- ("testInitValue", testInitValue),
- ("testInitValues", testInitValues)
- ]
- }
-
- extension MappedEnumTests {
- // DO NOT MODIFY: This is autogenerated, use:
- // `swift test --generate-linuxmain`
- // to regenerate.
- static let __allTests__MappedEnumTests = [
- ("testDecoder", testDecoder),
- ("testEncoder", testEncoder)
- ]
- }
-
- extension MappedValueCollectionRepresentedTests {
- // DO NOT MODIFY: This is autogenerated, use:
- // `swift test --generate-linuxmain`
- // to regenerate.
- static let __allTests__MappedValueCollectionRepresentedTests = [
- ("testRawValue", testRawValue),
- ("testRawValueFailure", testRawValueFailure),
- ("testString", testString),
- ("testStringFailure", testStringFailure)
- ]
- }
-
- extension MappedValueDictionaryRepresentedTests {
- // DO NOT MODIFY: This is autogenerated, use:
- // `swift test --generate-linuxmain`
- // to regenerate.
- static let __allTests__MappedValueDictionaryRepresentedTests = [
- ("testRawValue", testRawValue),
- ("testRawValueFailure", testRawValueFailure),
- ("testString", testString),
- ("testStringFailure", testStringFailure)
- ]
- }
-
- extension MappedValueRepresentableTests {
- // DO NOT MODIFY: This is autogenerated, use:
- // `swift test --generate-linuxmain`
- // to regenerate.
- static let __allTests__MappedValueRepresentableTests = [
- ("testStringValue", testStringValue)
- ]
- }
-
- public func __allTests() -> [XCTestCaseEntry] {
- return [
- testCase(EnumSetTests.__allTests__EnumSetTests),
- testCase(MappedEnumTests.__allTests__MappedEnumTests),
- testCase(MappedValueCollectionRepresentedTests.__allTests__MappedValueCollectionRepresentedTests),
- testCase(MappedValueDictionaryRepresentedTests.__allTests__MappedValueDictionaryRepresentedTests),
- testCase(MappedValueRepresentableTests.__allTests__MappedValueRepresentableTests)
- ]
- }
-#endif
diff --git a/bitrise.yml b/bitrise.yml
deleted file mode 100644
index 384706a..0000000
--- a/bitrise.yml
+++ /dev/null
@@ -1,40 +0,0 @@
----
-format_version: '8'
-default_step_lib_source: 'https://github.com/bitrise-io/bitrise-steplib.git'
-project_type: other
-app:
- envs:
- - PACKAGE_NAME: Options
-workflows:
- ci:
- steps:
- - git-clone@4: {}
- - script@1:
- inputs:
- - content: >-
- #!/usr/bin/env bash # fail if any commands fails
-
- set -e
-
- # debug log
-
- set -x
-
- pwd
-
- ls
-
- swift run swiftformat --lint . && swift run swiftlint
-
- swift build
-
- swift test --enable-code-coverage
-
-
- xcrun llvm-cov export -format="lcov" .build/debug/${PACKAGE_NAME}PackageTests.xctest/Contents/MacOS/${PACKAGE_NAME}PackageTests -instr-profile .build/debug/codecov/default.profdata > info.lcov
-
- bash <(curl https://codecov.io/bash) -F bitrise -F macOS -n
- $BITRISE_BUILD_NUMBER
-trigger_map:
-- push_branch: '*'
- workflow: ci
diff --git a/project.yml b/project.yml
new file mode 100644
index 0000000..abfabb5
--- /dev/null
+++ b/project.yml
@@ -0,0 +1,13 @@
+name: Options
+settings:
+ LINT_MODE: ${LINT_MODE}
+packages:
+ StealthyStash:
+ path: .
+aggregateTargets:
+ Lint:
+ buildScripts:
+ - path: Scripts/lint.sh
+ name: Lint
+ basedOnDependencyAnalysis: false
+ schemes: {}
\ No newline at end of file