55use Closure ;
66use Psr \Cache \CacheItemInterface ;
77use Psr \Cache \CacheItemPoolInterface ;
8+ use Stringable ;
89use Tempest \Cache \Config \CacheConfig ;
910use Tempest \DateTime \DateTime ;
1011use Tempest \DateTime \DateTimeInterface ;
1112use Tempest \DateTime \Duration ;
13+ use Tempest \Support \Arr ;
1214
1315final class GenericCache implements Cache
1416{
@@ -20,10 +22,10 @@ public function __construct(
2022 $ this ->adapter ??= $ this ->cacheConfig ->createAdapter ();
2123 }
2224
23- public function put (string $ key , mixed $ value , null |Duration |DateTimeInterface $ expiration = null ): CacheItemInterface
25+ public function put (Stringable | string $ key , mixed $ value , null |Duration |DateTimeInterface $ expiration = null ): CacheItemInterface
2426 {
2527 $ item = $ this ->adapter
26- ->getItem ($ key )
28+ ->getItem (( string ) $ key )
2729 ->set ($ value );
2830
2931 if ($ expiration instanceof Duration) {
@@ -41,37 +43,97 @@ public function put(string $key, mixed $value, null|Duration|DateTimeInterface $
4143 return $ item ;
4244 }
4345
44- public function get (string $ key ): mixed
46+ public function putMany (iterable $ values , null |Duration |DateTimeInterface $ expiration = null ): array
47+ {
48+ $ items = [];
49+
50+ foreach ($ values as $ key => $ value ) {
51+ $ items [(string ) $ key ] = $ this ->put ($ key , $ value , $ expiration );
52+ }
53+ return $ items ;
54+ }
55+
56+ public function increment (Stringable |string $ key , int $ by = 1 ): int
57+ {
58+ if (! $ this ->enabled ) {
59+ return 0 ;
60+ }
61+
62+ $ item = $ this ->adapter ->getItem ((string ) $ key );
63+
64+ if (! $ item ->isHit ()) {
65+ $ item ->set ($ by );
66+ } elseif (! is_numeric ($ item ->get ())) {
67+ throw new NotNumberException ((string ) $ key );
68+ } else {
69+ $ item ->set (((int ) $ item ->get ()) + $ by );
70+ }
71+
72+ $ this ->adapter ->save ($ item );
73+
74+ return (int ) $ item ->get ();
75+ }
76+
77+ public function decrement (Stringable |string $ key , int $ by = 1 ): int
78+ {
79+ if (! $ this ->enabled ) {
80+ return 0 ;
81+ }
82+
83+ $ item = $ this ->adapter ->getItem ((string ) $ key );
84+
85+ if (! $ item ->isHit ()) {
86+ $ item ->set (-$ by );
87+ } elseif (! is_numeric ($ item ->get ())) {
88+ throw new NotNumberException ((string ) $ key );
89+ } else {
90+ $ item ->set (((int ) $ item ->get ()) - $ by );
91+ }
92+
93+ $ this ->adapter ->save ($ item );
94+
95+ return (int ) $ item ->get ();
96+ }
97+
98+ public function get (Stringable |string $ key ): mixed
4599 {
46100 if (! $ this ->enabled ) {
47101 return null ;
48102 }
49103
50- return $ this ->adapter ->getItem ($ key )->get ();
104+ return $ this ->adapter ->getItem ((string ) $ key )->get ();
105+ }
106+
107+ public function getMany (iterable $ key ): array
108+ {
109+ return Arr \map_with_keys (
110+ array: $ key ,
111+ map: fn (string |Stringable $ key ) => yield (string ) $ key => $ this ->adapter ->getItem ((string ) $ key )->get (),
112+ );
51113 }
52114
53- public function resolve (string $ key , Closure $ callback , null |Duration |DateTimeInterface $ expiration = null ): mixed
115+ public function resolve (Stringable | string $ key , Closure $ callback , null |Duration |DateTimeInterface $ expiration = null ): mixed
54116 {
55117 if (! $ this ->enabled ) {
56118 return $ callback ();
57119 }
58120
59- $ item = $ this ->adapter ->getItem ($ key );
121+ $ item = $ this ->adapter ->getItem (( string ) $ key );
60122
61123 if (! $ item ->isHit ()) {
62- $ item = $ this ->put ($ key , $ callback (), $ expiration );
124+ $ item = $ this ->put (( string ) $ key , $ callback (), $ expiration );
63125 }
64126
65127 return $ item ->get ();
66128 }
67129
68- public function remove (string $ key ): void
130+ public function remove (Stringable | string $ key ): void
69131 {
70132 if (! $ this ->enabled ) {
71133 return ;
72134 }
73135
74- $ this ->adapter ->deleteItem ($ key );
136+ $ this ->adapter ->deleteItem (( string ) $ key );
75137 }
76138
77139 public function clear (): void
0 commit comments