1<?php 2 3/** 4 * This file is part of the ramsey/collection library 5 * 6 * For the full copyright and license information, please view the LICENSE 7 * file that was distributed with this source code. 8 * 9 * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> 10 * @license http://opensource.org/licenses/MIT MIT 11 */ 12 13declare(strict_types=1); 14 15namespace Ramsey\Collection\Map; 16 17use Ramsey\Collection\Tool\TypeTrait; 18 19/** 20 * A `TypedMap` represents a map of elements where key and value are typed. 21 * 22 * Each element is identified by a key with defined type and a value of defined 23 * type. The keys of the map must be unique. The values on the map can be= 24 * repeated but each with its own different key. 25 * 26 * The most common case is to use a string type key, but it's not limited to 27 * this type of keys. 28 * 29 * This is a direct implementation of `TypedMapInterface`, provided for the sake 30 * of convenience. 31 * 32 * Example usage: 33 * 34 * ```php 35 * $map = new TypedMap('string', Foo::class); 36 * $map['x'] = new Foo(); 37 * foreach ($map as $key => $value) { 38 * // do something with $key, it will be a Foo::class 39 * } 40 * 41 * // this will throw an exception since key must be string 42 * $map[10] = new Foo(); 43 * 44 * // this will throw an exception since value must be a Foo 45 * $map['bar'] = 'bar'; 46 * 47 * // initialize map with contents 48 * $map = new TypedMap('string', Foo::class, [ 49 * new Foo(), new Foo(), new Foo() 50 * ]); 51 * ``` 52 * 53 * It is preferable to subclass `AbstractTypedMap` to create your own typed map 54 * implementation: 55 * 56 * ```php 57 * class FooTypedMap extends AbstractTypedMap 58 * { 59 * public function getKeyType() 60 * { 61 * return 'int'; 62 * } 63 * 64 * public function getValueType() 65 * { 66 * return Foo::class; 67 * } 68 * } 69 * ``` 70 * 71 * … but you also may use the `TypedMap` class: 72 * 73 * ```php 74 * class FooTypedMap extends TypedMap 75 * { 76 * public function __constructor(array $data = []) 77 * { 78 * parent::__construct('int', Foo::class, $data); 79 * } 80 * } 81 * ``` 82 * 83 * @template K 84 * @template T 85 * @extends AbstractTypedMap<K, T> 86 */ 87class TypedMap extends AbstractTypedMap 88{ 89 use TypeTrait; 90 91 /** 92 * The data type of keys stored in this collection. 93 * 94 * A map key's type is immutable once it is set. For this reason, this 95 * property is set private. 96 * 97 * @var string data type of the map key. 98 */ 99 private $keyType; 100 101 /** 102 * The data type of values stored in this collection. 103 * 104 * A map value's type is immutable once it is set. For this reason, this 105 * property is set private. 106 * 107 * @var string data type of the map value. 108 */ 109 private $valueType; 110 111 /** 112 * Constructs a map object of the specified key and value types, 113 * optionally with the specified data. 114 * 115 * @param string $keyType The data type of the map's keys. 116 * @param string $valueType The data type of the map's values. 117 * @param array<K, T> $data The initial data to set for this map. 118 */ 119 public function __construct(string $keyType, string $valueType, array $data = []) 120 { 121 $this->keyType = $keyType; 122 $this->valueType = $valueType; 123 124 /** @psalm-suppress MixedArgumentTypeCoercion */ 125 parent::__construct($data); 126 } 127 128 public function getKeyType(): string 129 { 130 return $this->keyType; 131 } 132 133 public function getValueType(): string 134 { 135 return $this->valueType; 136 } 137} 138