Skip to content

Commit

Permalink
Merge pull request #68 from rawilk/hash-key-generator
Browse files Browse the repository at this point in the history
[Feature]: Hash key generator
  • Loading branch information
rawilk authored Oct 16, 2024
2 parents 0448307 + f448d95 commit 2d93b02
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 0 deletions.
11 changes: 11 additions & 0 deletions config/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@
| Supported:
| - \Rawilk\Settings\Support\KeyGenerators\ReadableKeyGenerator
| - \Rawilk\Settings\Support\KeyGenerators\Md5KeyGenerator (default)
| - \Rawilk\Settings\Support\KeyGenerators\HashKeyGenerator
|
*/
'key_generator' => \Rawilk\Settings\Support\KeyGenerators\Md5KeyGenerator::class,
Expand Down Expand Up @@ -194,4 +195,14 @@
\Carbon\CarbonImmutable::class,
\Illuminate\Support\Carbon::class,
],

/*
|--------------------------------------------------------------------------
| Hash Algorithm
|--------------------------------------------------------------------------
|
| The hashing algorithm to use for the HashKeyGenerator.
|
*/
'hash_algorithm' => 'xxh128',
];
40 changes: 40 additions & 0 deletions src/Support/KeyGenerators/HashKeyGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

namespace Rawilk\Settings\Support\KeyGenerators;

use Rawilk\Settings\Contracts\ContextSerializer;
use Rawilk\Settings\Contracts\KeyGenerator as KeyGeneratorContract;
use Rawilk\Settings\Support\Context;
use RuntimeException;

class HashKeyGenerator implements KeyGeneratorContract
{
protected ContextSerializer $serializer;

public function generate(string $key, ?Context $context = null): string
{
return hash(
config('settings.hash_algorithm', 'xxh128'),
$key . $this->serializer->serialize($context),
);
}

public function removeContextFromKey(string $key): string
{
throw new RuntimeException('HashKeyGenerator does not support removing the context from the key.');
}

public function setContextSerializer(ContextSerializer $serializer): static
{
$this->serializer = $serializer;

return $this;
}

public function contextPrefix(): string
{
throw new RuntimeException('HashKeyGenerator does not support a context prefix.');
}
}
43 changes: 43 additions & 0 deletions tests/Unit/KeyGenerators/HashKeyGeneratorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

use Rawilk\Settings\Support\Context;
use Rawilk\Settings\Support\ContextSerializers\ContextSerializer;
use Rawilk\Settings\Support\ContextSerializers\DotNotationContextSerializer;
use Rawilk\Settings\Support\KeyGenerators\HashKeyGenerator;

beforeEach(function () {
$this->keyGenerator = (new HashKeyGenerator)
->setContextSerializer(new ContextSerializer);

config([
'settings.hash_algorithm' => 'xxh128',
]);
});

it('generates a hash of a key', function () {
// N; is for a serialized null context object
expect($this->keyGenerator->generate('my-key'))->toBe(hash('xxh128', 'my-keyN;'));
});

it('generates a hash of a key and context object', function () {
$context = new Context([
'id' => 123,
]);

expect($this->keyGenerator->generate('my-key', $context))
->toBe(hash('xxh128', 'my-key' . serialize($context)));
});

it('works with other context serializers', function () {
$this->keyGenerator->setContextSerializer(new DotNotationContextSerializer);

$context = new Context([
'id' => 123,
'bool-value' => false,
]);

expect($this->keyGenerator->generate('my-key', $context))
->toBe(hash('xxh128', 'my-keyid:123::bool-value:0'));
});

0 comments on commit 2d93b02

Please sign in to comment.