From 03b433b4ffd9cb24fc94a04328f5f8c111444f82 Mon Sep 17 00:00:00 2001 From: Greg Bowler Date: Mon, 4 May 2026 15:29:21 +0100 Subject: [PATCH 1/7] ci: improve workflows --- .github/workflows/ci.yml | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a7b2b4e..b71fd6f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,6 +4,10 @@ on: push: pull_request: +permissions: + contents: read + actions: read + jobs: composer: runs-on: ubuntu-latest @@ -34,6 +38,7 @@ jobs: with: name: build-artifact-${{ matrix.php }} path: /tmp/github-actions + retention-days: 1 phpunit: runs-on: ubuntu-latest @@ -89,9 +94,10 @@ jobs: run: cat "_coverage/coverage.txt" - name: Upload to Codecov - uses: codecov/codecov-action@v5 + uses: codecov/codecov-action@v6 with: token: ${{ secrets.CODECOV_TOKEN }} + slug: ${{ github.repository }} phpstan: runs-on: ubuntu-latest @@ -163,21 +169,3 @@ jobs: php_version: ${{ matrix.php }} path: src/ standard: phpcs.xml - - remove_old_artifacts: - runs-on: ubuntu-latest - - permissions: - actions: write - - steps: - - name: Remove old artifacts for prior workflow runs on this repository - env: - GH_TOKEN: ${{ github.token }} - run: | - gh api "/repos/${{ github.repository }}/actions/artifacts" | jq ".artifacts[] | select(.name | startswith(\"build-artifact\")) | .id" > artifact-id-list.txt - while read id - do - echo -n "Deleting artifact ID $id ... " - gh api --method DELETE /repos/${{ github.repository }}/actions/artifacts/$id && echo "Done" - done Date: Mon, 4 May 2026 15:30:40 +0100 Subject: [PATCH 2/7] build: add test scripts --- composer.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/composer.json b/composer.json index a45c9cc..a7145b4 100644 --- a/composer.json +++ b/composer.json @@ -29,6 +29,19 @@ } ], + "scripts": { + "phpunit": "vendor/bin/phpunit --configuration phpunit.xml", + "phpstan": "vendor/bin/phpstan analyse --level 6 src --memory-limit 256M", + "phpcs": "vendor/bin/phpcs src --standard=phpcs.xml", + "phpmd": "vendor/bin/phpmd src/ text phpmd.xml", + "test": [ + "@phpunit", + "@phpstan", + "@phpcs", + "@phpmd" + ] + }, + "autoload": { "psr-4": { "Gt\\TypeSafeGetter\\": "./src" From 7855fdd7969f938841c389f024eaa0aafceb7107 Mon Sep 17 00:00:00 2001 From: Greg Bowler Date: Mon, 4 May 2026 15:35:08 +0100 Subject: [PATCH 3/7] build: upgrade dependencies --- composer.json | 4 ++ composer.lock | 118 +++++++++++++++++++++++++------------------------- 2 files changed, 62 insertions(+), 60 deletions(-) diff --git a/composer.json b/composer.json index a7145b4..3314df0 100644 --- a/composer.json +++ b/composer.json @@ -42,6 +42,10 @@ ] }, + "platform": { + "php": "8.2" + }, + "autoload": { "psr-4": { "Gt\\TypeSafeGetter\\": "./src" diff --git a/composer.lock b/composer.lock index fdb220e..a4f08a4 100644 --- a/composer.lock +++ b/composer.lock @@ -2154,34 +2154,34 @@ }, { "name": "symfony/config", - "version": "v6.4.34", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "ce9cb0c0d281aaf188b802d4968e42bfb60701e9" + "reference": "d4a277b7a0f26487db16b264d935c617b7d994ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/ce9cb0c0d281aaf188b802d4968e42bfb60701e9", - "reference": "ce9cb0c0d281aaf188b802d4968e42bfb60701e9", + "url": "https://api.github.com/repos/symfony/config/zipball/d4a277b7a0f26487db16b264d935c617b7d994ea", + "reference": "d4a277b7a0f26487db16b264d935c617b7d994ea", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/filesystem": "^5.4|^6.0|^7.0", + "symfony/filesystem": "^7.1|^8.0", "symfony/polyfill-ctype": "~1.8" }, "conflict": { - "symfony/finder": "<5.4", + "symfony/finder": "<6.4", "symfony/service-contracts": "<2.5" }, "require-dev": { - "symfony/event-dispatcher": "^5.4|^6.0|^7.0", - "symfony/finder": "^5.4|^6.0|^7.0", - "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0|^8.0", + "symfony/finder": "^6.4|^7.0|^8.0", + "symfony/messenger": "^6.4|^7.0|^8.0", "symfony/service-contracts": "^2.5|^3", - "symfony/yaml": "^5.4|^6.0|^7.0" + "symfony/yaml": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -2209,7 +2209,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v6.4.34" + "source": "https://github.com/symfony/config/tree/v7.4.9" }, "funding": [ { @@ -2229,44 +2229,43 @@ "type": "tidelift" } ], - "time": "2026-02-24T17:34:50+00:00" + "time": "2026-04-29T14:25:20+00:00" }, { "name": "symfony/dependency-injection", - "version": "v6.4.35", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "d95712d0e9446b9f244b64811ffb6af7b7434213" + "reference": "27cd9f912438d07ced76008bc66cf8b0cf4de622" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/d95712d0e9446b9f244b64811ffb6af7b7434213", - "reference": "d95712d0e9446b9f244b64811ffb6af7b7434213", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/27cd9f912438d07ced76008bc66cf8b0cf4de622", + "reference": "27cd9f912438d07ced76008bc66cf8b0cf4de622", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "psr/container": "^1.1|^2.0", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/service-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.4.20|^7.2.5" + "symfony/service-contracts": "^3.6", + "symfony/var-exporter": "^6.4.20|^7.2.5|^8.0" }, "conflict": { "ext-psr": "<1.1|>=2", - "symfony/config": "<6.1", - "symfony/finder": "<5.4", - "symfony/proxy-manager-bridge": "<6.3", - "symfony/yaml": "<5.4" + "symfony/config": "<6.4", + "symfony/finder": "<6.4", + "symfony/yaml": "<6.4" }, "provide": { "psr/container-implementation": "1.1|2.0", "symfony/service-implementation": "1.1|2.0|3.0" }, "require-dev": { - "symfony/config": "^6.1|^7.0", - "symfony/expression-language": "^5.4|^6.0|^7.0", - "symfony/yaml": "^5.4|^6.0|^7.0" + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/expression-language": "^6.4|^7.0|^8.0", + "symfony/yaml": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -2294,7 +2293,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v6.4.35" + "source": "https://github.com/symfony/dependency-injection/tree/v7.4.9" }, "funding": [ { @@ -2314,7 +2313,7 @@ "type": "tidelift" } ], - "time": "2026-02-26T12:16:01+00:00" + "time": "2026-04-30T18:38:49+00:00" }, { "name": "symfony/deprecation-contracts", @@ -2385,25 +2384,25 @@ }, { "name": "symfony/filesystem", - "version": "v6.4.34", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "01ffe0411b842f93c571e5c391f289c3fdd498c3" + "reference": "dcd8f96bcdc0f128ec406c765cc066c6035d1be3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/01ffe0411b842f93c571e5c391f289c3fdd498c3", - "reference": "01ffe0411b842f93c571e5c391f289c3fdd498c3", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/dcd8f96bcdc0f128ec406c765cc066c6035d1be3", + "reference": "dcd8f96bcdc0f128ec406c765cc066c6035d1be3", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, "require-dev": { - "symfony/process": "^5.4|^6.4|^7.0" + "symfony/process": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -2431,7 +2430,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.4.34" + "source": "https://github.com/symfony/filesystem/tree/v7.4.9" }, "funding": [ { @@ -2451,20 +2450,20 @@ "type": "tidelift" } ], - "time": "2026-02-24T17:51:06+00:00" + "time": "2026-04-18T13:18:21+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + "reference": "141046a8f9477948ff284fa65be2095baafb94f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2", "shasum": "" }, "require": { @@ -2514,7 +2513,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.37.0" }, "funding": [ { @@ -2534,20 +2533,20 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", - "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6a21eb99c6973357967f6ce3708cd55a6bec6315", + "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315", "shasum": "" }, "require": { @@ -2599,7 +2598,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.37.0" }, "funding": [ { @@ -2619,7 +2618,7 @@ "type": "tidelift" } ], - "time": "2024-12-23T08:48:59+00:00" + "time": "2026-04-10T17:25:58+00:00" }, { "name": "symfony/service-contracts", @@ -2710,26 +2709,25 @@ }, { "name": "symfony/var-exporter", - "version": "v6.4.26", + "version": "v8.0.9", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "466fcac5fa2e871f83d31173f80e9c2684743bfc" + "reference": "24cf67be4dd0926e4413635418682f4fff831412" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/466fcac5fa2e871f83d31173f80e9c2684743bfc", - "reference": "466fcac5fa2e871f83d31173f80e9c2684743bfc", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/24cf67be4dd0926e4413635418682f4fff831412", + "reference": "24cf67be4dd0926e4413635418682f4fff831412", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3" + "php": ">=8.4" }, "require-dev": { - "symfony/property-access": "^6.4|^7.0", - "symfony/serializer": "^6.4|^7.0", - "symfony/var-dumper": "^5.4|^6.0|^7.0" + "symfony/property-access": "^7.4|^8.0", + "symfony/serializer": "^7.4|^8.0", + "symfony/var-dumper": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -2767,7 +2765,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v6.4.26" + "source": "https://github.com/symfony/var-exporter/tree/v8.0.9" }, "funding": [ { @@ -2787,7 +2785,7 @@ "type": "tidelift" } ], - "time": "2025-09-11T09:57:09+00:00" + "time": "2026-04-18T13:51:42+00:00" }, { "name": "theseer/tokenizer", From 80e5b8e247c0a9cbf0a6764ac0c250c4345ae695 Mon Sep 17 00:00:00 2001 From: Greg Bowler Date: Mon, 4 May 2026 15:52:16 +0100 Subject: [PATCH 4/7] build: php 8.2 compat --- composer.json | 6 ++++-- composer.lock | 26 +++++++++++++++----------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/composer.json b/composer.json index 3314df0..346ed6e 100644 --- a/composer.json +++ b/composer.json @@ -42,8 +42,10 @@ ] }, - "platform": { - "php": "8.2" + "config": { + "platform": { + "php": "8.2" + } }, "autoload": { diff --git a/composer.lock b/composer.lock index a4f08a4..72228d3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8741f9ae0379e72c81f108cc84f5df9b", + "content-hash": "a607ea873e39b7d7b855df8933e7e115", "packages": [], "packages-dev": [ { @@ -2709,25 +2709,26 @@ }, { "name": "symfony/var-exporter", - "version": "v8.0.9", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "24cf67be4dd0926e4413635418682f4fff831412" + "reference": "22e03a49c95ef054a43601cd159b222bfab1c701" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/24cf67be4dd0926e4413635418682f4fff831412", - "reference": "24cf67be4dd0926e4413635418682f4fff831412", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/22e03a49c95ef054a43601cd159b222bfab1c701", + "reference": "22e03a49c95ef054a43601cd159b222bfab1c701", "shasum": "" }, "require": { - "php": ">=8.4" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" }, "require-dev": { - "symfony/property-access": "^7.4|^8.0", - "symfony/serializer": "^7.4|^8.0", - "symfony/var-dumper": "^7.4|^8.0" + "symfony/property-access": "^6.4|^7.0|^8.0", + "symfony/serializer": "^6.4|^7.0|^8.0", + "symfony/var-dumper": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -2765,7 +2766,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v8.0.9" + "source": "https://github.com/symfony/var-exporter/tree/v7.4.9" }, "funding": [ { @@ -2785,7 +2786,7 @@ "type": "tidelift" } ], - "time": "2026-04-18T13:51:42+00:00" + "time": "2026-04-18T13:18:21+00:00" }, { "name": "theseer/tokenizer", @@ -2847,5 +2848,8 @@ "php": ">=8.0" }, "platform-dev": {}, + "platform-overrides": { + "php": "8.2" + }, "plugin-api-version": "2.9.0" } From 26b208563649c0245d6bb9766845a2158849c6a7 Mon Sep 17 00:00:00 2001 From: Greg Bowler Date: Mon, 4 May 2026 16:06:39 +0100 Subject: [PATCH 5/7] tidy: Gt->GT --- README.md | 8 ++++---- composer.json | 3 ++- src/CallbackTypeSafeGetter.php | 2 +- src/NullableTypeSafeGetter.php | 2 +- src/TypeSafeGetter.php | 2 +- test/phpunit/ExampleClass.php | 2 +- test/phpunit/TestGetter.php | 6 +++--- test/phpunit/TypeSafeGetterTest.php | 2 +- 8 files changed, 14 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index ef4c1ef..7bc1314 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ An interface for objects that expose type-safe getter methods. ============================================================== -Throughout PHP.Gt repositories, wherever an object represents enclosed data, a consistent interface is used to expose the data in a type-safe manner. +Throughout PHP.GT repositories, wherever an object represents enclosed data, a consistent interface is used to expose the data in a type-safe manner. *** @@ -18,7 +18,7 @@ Throughout PHP.Gt repositories, wherever an object represents enclosed data, a c Current version - PHP.Gt/TypeSafeGetter documentation + PHP.GT/TypeSafeGetter documentation The following methods are defined by this interface: @@ -36,12 +36,12 @@ Common areas you will see this interface used: + Database rows + User input (from the query string or posted form data) + Session and cookie storage -+ PHP.Gt's [DataObject](https://www.php.gt/dataobject) repository. ++ PHP.GT's [DataObject](https://www.php.gt/dataobject) repository. `NullableTypeSafeGetter` trait ------------------------------ -A lot of repositories within PHP.Gt that utilise this class were repeating the same getter code, so this trait was introduced to remove the repetition. All getter functions of the interface are implemented, introducing a protected helper function `getNullableType` which removes the repetition of checking null values before casting them. The `getNullableType` function also allows a callback to be passed as the type parameter, allowing more complex nullable types to be constructed. +A lot of repositories within PHP.GT that utilise this class were repeating the same getter code, so this trait was introduced to remove the repetition. All getter functions of the interface are implemented, introducing a protected helper function `getNullableType` which removes the repetition of checking null values before casting them. The `getNullableType` function also allows a callback to be passed as the type parameter, allowing more complex nullable types to be constructed. # Proudly sponsored by diff --git a/composer.json b/composer.json index 346ed6e..a704b2e 100644 --- a/composer.json +++ b/composer.json @@ -50,12 +50,13 @@ "autoload": { "psr-4": { + "GT\\TypeSafeGetter\\": "./src", "Gt\\TypeSafeGetter\\": "./src" } }, "autoload-dev": { "psr-4": { - "Gt\\TypeSafeGetter\\Test\\": "./test/phpunit" + "GT\\TypeSafeGetter\\Test\\": "./test/phpunit" } } } diff --git a/src/CallbackTypeSafeGetter.php b/src/CallbackTypeSafeGetter.php index a6f9a4f..4b1c7bc 100644 --- a/src/CallbackTypeSafeGetter.php +++ b/src/CallbackTypeSafeGetter.php @@ -1,5 +1,5 @@ Date: Mon, 4 May 2026 16:16:03 +0100 Subject: [PATCH 6/7] build: php 8.2 compat --- composer.json | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index a704b2e..5bdcc3d 100644 --- a/composer.json +++ b/composer.json @@ -42,12 +42,6 @@ ] }, - "config": { - "platform": { - "php": "8.2" - } - }, - "autoload": { "psr-4": { "GT\\TypeSafeGetter\\": "./src", @@ -58,5 +52,9 @@ "psr-4": { "GT\\TypeSafeGetter\\Test\\": "./test/phpunit" } + }, + "config": { + "platform": { + } } } From 53551a12936ab66db563804c888405493b38ed12 Mon Sep 17 00:00:00 2001 From: Greg Bowler Date: Mon, 4 May 2026 16:32:53 +0100 Subject: [PATCH 7/7] ci: codacy --- .codacy.yml | 4 ++++ README.md | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 .codacy.yml diff --git a/.codacy.yml b/.codacy.yml new file mode 100644 index 0000000..008d53b --- /dev/null +++ b/.codacy.yml @@ -0,0 +1,4 @@ +exclude_paths: + - ".github/**" + - "example/**" + - "test/**" diff --git a/README.md b/README.md index 7bc1314..a94557c 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,59 @@ Throughout PHP.GT repositories, wherever an object represents enclosed data, a c PHP.GT/TypeSafeGetter documentation +This package defines: + ++ `GT\TypeSafeGetter\TypeSafeGetter` ++ `GT\TypeSafeGetter\NullableTypeSafeGetter` ++ `GT\TypeSafeGetter\CallbackTypeSafeGetter` + +The usual pattern is to implement `get()` yourself and use the `NullableTypeSafeGetter` trait for the common typed methods. + +```php +use DateTimeImmutable; +use DateTimeInterface; +use GT\TypeSafeGetter\NullableTypeSafeGetter; +use GT\TypeSafeGetter\TypeSafeGetter; + +class DataStore implements TypeSafeGetter { + use NullableTypeSafeGetter; + + public function __construct( + private readonly array $data = [], + ) {} + + public function get(string $name):mixed { + return $this->data[$name] ?? null; + } +} + +$store = new DataStore([ + "id" => "42", + "active" => 1, + "created" => "2024-05-01 09:15:00", +]); + +echo $store->getInt("id"); +var_dump($store->getBool("active")); +echo $store->getDateTime("created")?->format("Y-m-d"); +``` + +`getInstance()` returns an existing object after checking its type: + +```php +$store = new DataStore([ + "date" => new DateTimeImmutable("2024-05-01"), +]); + +$date = $store->getInstance("date", DateTimeInterface::class); +``` + +`getDateTime()` accepts: + ++ `DateTimeInterface` instances ++ Unix timestamps ++ date/time strings supported by `DateTimeImmutable` + The following methods are defined by this interface: + `get(string $name):mixed` - A non-type-safe getter, used for getting keys that are not of an inbuilt type @@ -36,6 +89,8 @@ Common areas you will see this interface used: + Database rows + User input (from the query string or posted form data) + Session and cookie storage ++ HTTP header collections ++ Configuration objects + PHP.GT's [DataObject](https://www.php.gt/dataobject) repository. `NullableTypeSafeGetter` trait @@ -43,6 +98,13 @@ Common areas you will see this interface used: A lot of repositories within PHP.GT that utilise this class were repeating the same getter code, so this trait was introduced to remove the repetition. All getter functions of the interface are implemented, introducing a protected helper function `getNullableType` which removes the repetition of checking null values before casting them. The `getNullableType` function also allows a callback to be passed as the type parameter, allowing more complex nullable types to be constructed. +`CallbackTypeSafeGetter` interface +---------------------------------- + +This interface is for callback-driven lookups where a value may need to be fetched or computed as part of the read operation, such as cache APIs. + +Unlike `NullableTypeSafeGetter`, there is no trait implementation in this package for the callback interface. Implementing classes define their own callback behaviour. + # Proudly sponsored by [JetBrains Open Source sponsorship program](https://www.jetbrains.com/community/opensource/)