Skip to content

Commit f69601d

Browse files
committed
Merge branch 'develop'
* develop: specify next release update documentation make Stop and Failed internal classes use continuation pattern when pinging CS
2 parents 280ee1e + f78e839 commit f69601d

13 files changed

Lines changed: 209 additions & 185 deletions

File tree

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# Changelog
22

3+
## 4.0.0 - 2024-03-10
4+
5+
### Changed
6+
7+
- When the ping callable is called it must return a `Innmind\FileWatch\Continuation`
8+
9+
### Removed
10+
11+
- `Innmind\FileWatch\Stop`
12+
- `Innmind\FileWatch\Failed`
13+
314
## 3.2.0 - 2023-11-12
415

516
### Added

README.md

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,27 +35,23 @@ $watch = Factory::build(
3535
new Usleep,
3636
);
3737

38-
$count = $watch(Path::of('/to/some/file/or/folder'))(0, function(int $count): Either {
38+
$count = $watch(Path::of('/to/some/file/or/folder'))(0, function(int $count, Continuation $continuation): Continuation {
3939
// this function is called every time the file is modified
4040
++$count;
4141

4242
if ($count === 42) {
43-
// by returning a Stop instance on the left side it will instruct to
44-
// stop watching for changes and the value in the Stop will be moved on
45-
// the right side to the caller
46-
return Either::left(Stop::of($count));
43+
// This will stop watching the folder for changes and return the count
44+
return $continuation->stop($count);
4745
}
4846

49-
if ($forSomeReason) {
50-
// by returning a left value it will stop watching for changes and the
51-
// Either will be returned as is to the caller
52-
return Either::left($someReason);
53-
}
54-
55-
// by returning a right side it will instruct to continue watching for changes
56-
// and the value will be passed to this callable the next time it's called
57-
return Either::right($count);
58-
});
47+
// This will instruct to continue watching for changes and the value will be
48+
// passed to this callable the next time it's called
49+
return $continuation->continue($count);
50+
})->match(
51+
static fn(int $count) => $count, // always 42 as it's the stopping value
52+
static fn() => throw new \RuntimeException('Failed to watch for changes'),
53+
);
5954
```
6055

61-
**Note**: The function may be called multiple times for an single change due to the way `tail` and `stat` works.
56+
> [!WARNING]
57+
> The function may be called multiple times for an single change due to the way `tail` and `stat` works.

src/Continuation.php

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
declare(strict_types = 1);
3+
4+
namespace Innmind\FileWatch;
5+
6+
use Innmind\FileWatch\Continuation\State;
7+
8+
/**
9+
* @psalm-immutable
10+
* @template T
11+
*/
12+
final class Continuation
13+
{
14+
private State $state;
15+
/** @var T */
16+
private mixed $value;
17+
18+
/**
19+
* @param T $value
20+
*/
21+
private function __construct(State $state, mixed $value)
22+
{
23+
$this->state = $state;
24+
$this->value = $value;
25+
}
26+
27+
/**
28+
* @psalm-pure
29+
* @internal
30+
* @template A
31+
*
32+
* @param A $value
33+
*
34+
* @return self<A>
35+
*/
36+
public static function of(mixed $value): self
37+
{
38+
return new self(State::continue, $value);
39+
}
40+
41+
/**
42+
* @template U
43+
*
44+
* @param U $value
45+
*
46+
* @return self<U>
47+
*/
48+
public function continue(mixed $value): self
49+
{
50+
return new self(State::continue, $value);
51+
}
52+
53+
/**
54+
* @template U
55+
*
56+
* @param U $value
57+
*
58+
* @return self<U>
59+
*/
60+
public function stop(mixed $value): self
61+
{
62+
return new self(State::stop, $value);
63+
}
64+
65+
/**
66+
* @internal
67+
* @template R
68+
*
69+
* @param callable(T): R $continue
70+
* @param callable(T): R $stop
71+
*
72+
* @return R
73+
*/
74+
public function match(
75+
callable $continue,
76+
callable $stop,
77+
): mixed {
78+
/** @psalm-suppress ImpureFunctionCall */
79+
return match ($this->state) {
80+
State::continue => $continue($this->value),
81+
State::stop => $stop($this->value),
82+
};
83+
}
84+
}

src/Continuation/State.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
declare(strict_types = 1);
3+
4+
namespace Innmind\FileWatch\Continuation;
5+
6+
/**
7+
* @psalm-immutable
8+
*/
9+
enum State
10+
{
11+
case continue;
12+
case stop;
13+
}

src/Failed.php

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/Ping.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33

44
namespace Innmind\FileWatch;
55

6-
use Innmind\Immutable\Either;
6+
use Innmind\Immutable\Maybe;
77

88
interface Ping
99
{
1010
/**
1111
* @template C
12-
* @template L
12+
* @template R
1313
*
1414
* @param C $carry
15-
* @param callable(C): Either<L|Stop<C>, C> $ping
15+
* @param callable(R|C, Continuation<R|C>): Continuation<R> $ping
1616
*
17-
* @return Either<Failed|L, C>
17+
* @return Maybe<R|C>
1818
*/
19-
public function __invoke(mixed $carry, callable $ping): Either;
19+
public function __invoke(mixed $carry, callable $ping): Maybe;
2020
}

src/Ping/Failed.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
declare(strict_types = 1);
3+
4+
namespace Innmind\FileWatch\Ping;
5+
6+
/**
7+
* @internal
8+
*/
9+
final class Failed
10+
{
11+
}

src/Ping/Fallback.php

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,8 @@
33

44
namespace Innmind\FileWatch\Ping;
55

6-
use Innmind\FileWatch\{
7-
Ping,
8-
Failed,
9-
Stop,
10-
};
11-
use Innmind\Immutable\Either;
6+
use Innmind\FileWatch\Ping;
7+
use Innmind\Immutable\Maybe;
128

139
final class Fallback implements Ping
1410
{
@@ -21,26 +17,10 @@ public function __construct(Ping $attempt, Ping $fallback)
2117
$this->fallback = $fallback;
2218
}
2319

24-
/**
25-
* @template C
26-
* @template L
27-
*
28-
* @param C $carry
29-
* @param callable(C): Either<L|Stop<C>, C> $ping
30-
*
31-
* @return Either<Failed|L, C>
32-
*/
33-
public function __invoke(mixed $carry, callable $ping): Either
20+
public function __invoke(mixed $carry, callable $ping): Maybe
3421
{
35-
/**
36-
* @psalm-suppress InvalidArgument
37-
* @var Either<Failed|L, C>
38-
*/
3922
return ($this->attempt)($carry, $ping)->otherwise(
40-
fn($left) => match ($left instanceof Failed) {
41-
true => ($this->fallback)($carry, $ping),
42-
false => Either::left($left),
43-
},
23+
fn() => ($this->fallback)($carry, $ping),
4424
);
4525
}
4626
}

src/Ping/Logger.php

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44
namespace Innmind\FileWatch\Ping;
55

66
use Innmind\FileWatch\{
7+
Continuation,
78
Ping,
8-
Stop,
9-
Failed,
109
};
1110
use Innmind\Url\Path;
12-
use Innmind\Immutable\Either;
11+
use Innmind\Immutable\Maybe;
1312
use Psr\Log\LoggerInterface;
1413

1514
final class Logger implements Ping
@@ -30,29 +29,32 @@ private function __construct(
3029

3130
/**
3231
* @template C
33-
* @template L
32+
* @template R
3433
*
3534
* @param C $carry
36-
* @param callable(C): Either<L|Stop<C>, C> $ping
35+
* @param callable(R|C, Continuation<R|C>): Continuation<R> $ping
3736
*
38-
* @return Either<Failed|L, C>
37+
* @return Maybe<R|C>
3938
*/
40-
public function __invoke(mixed $carry, callable $ping): Either
39+
public function __invoke(mixed $carry, callable $ping): Maybe
4140
{
4241
$this->logger->info( // todo use debug
4342
'Starting to watch {path}',
4443
['path' => $this->path->toString()],
4544
);
4645

47-
/** @var Either<Failed|L, C> */
48-
return ($this->ping)($carry, function(mixed $carry) use ($ping): Either {
46+
/**
47+
* @psalm-suppress InvalidArgument
48+
* @var Maybe<R|C>
49+
*/
50+
return ($this->ping)($carry, function(mixed $carry, Continuation $continuation) use ($ping): Continuation {
4951
/** @var C $carry */
5052
$this->logger->info(
5153
'Content at {path} changed',
5254
['path' => $this->path->toString()],
5355
);
5456

55-
return $ping($carry);
57+
return $ping($carry, $continuation);
5658
});
5759
}
5860

0 commit comments

Comments
 (0)