ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
Brick.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
26 use Closure;
29 
34 class Brick
35 {
38 
39  public function __construct()
40  {
41  $this->transform = new Transform();
42  $this->primitives = new Primitives();
43  }
44 
45  public function apply(Closure $parse, string $input): Result
46  {
47  return $this->consume($parse, new Intermediate($input))->then(static fn(Intermediate $x): Result => (
48  $x->transform(static fn($value): Result => (
49  new Ok(is_array($value) && !is_string(key($value)) ? current($value) : $value)
50  ))
51  ));
52  }
53 
58  public function toTransformation(Closure $parse): Transformation
59  {
60  return new Custom(fn($input) => $this->apply($parse, $input)->value());
61  }
62 
68  public function range(int $start, int $end): Closure
69  {
70  return static fn(Intermediate $x, Closure $cc): Result => $cc(
71  $x->value() >= $start && $x->value() <= $end ? $x->accept() : $x->reject()
72  );
73  }
74 
78  public function alpha(): Closure
79  {
80  return $this->primitives->simpleEither([
81  $this->range(0x41, 0x5A),
82  $this->range(0x61, 0x7A),
83  ]);
84  }
85 
89  public function digit(): Closure
90  {
91  return $this->range(0x30, 0x39);
92  }
93 
94  public function either(array $parsers): Closure
95  {
96  return $this->primitives->simpleEither($this->namesFromKeys($parsers));
97  }
98 
103  public function sequence(array $parsers): Closure
104  {
105  return $this->primitives->simpleSequence($this->namesFromKeys($parsers));
106  }
107 
114  public function repeat(int $min, ?int $max, $parse): Closure
115  {
116  $min = max(0, $min);
117  $max = null === $max ? null : max($min, $max) - $min;
118 
119  return $this->primitives->simpleSequence([
120  ...array_fill(0, $min, $parse),
121  $this->primitives->until($max, $parse)
122  ]);
123  }
124 
130  public function transformation(Transformation $transformation, Closure $parse): Closure
131  {
132  return $this->transform->to($transformation, $parse);
133  }
134 
139  private function namesFromKeys(array $array): array
140  {
141  return array_map(
142  function ($key) use ($array): Closure {
143  $current = $this->primitives->parserFrom($array[$key]);
144  return is_string($key) ? $this->transform->as($key, $current) : $current;
145  },
146  array_keys($array)
147  );
148  }
149 
157  private function consume(Closure $parse, Intermediate $intermediate): Result
158  {
159  return $parse($intermediate, static fn(Result $x): Result => $x->then(
160  static fn(Intermediate $x): Result => $x->done() ? new Ok($x) : new Error('EOF not reached.')
161  ));
162  }
163 }
then(callable $f)
Get a new result from the callable or do nothing if this is an error.
transform(Closure $transform)
Calls the given closure with all accepted values.
transformation(Transformation $transformation, Closure $parse)
Definition: Brick.php:130
consume(Closure $parse, Intermediate $intermediate)
It just checks if the given input is fully consumed after parsing and rejects the input otherwise...
Definition: Brick.php:157
repeat(int $min, ?int $max, $parse)
Definition: Brick.php:114
-type Continuation Closure(Result<Intermediate>): Result<Intermediate> -type Parser Closure(Intermedi...
Definition: Primitives.php:32
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
toTransformation(Closure $parse)
Definition: Brick.php:58
A result encapsulates a value or an error and simplifies the handling of those.
Definition: Ok.php:30
either(array $parsers)
Definition: Brick.php:94
A transformation is a function from one datatype to another.
sequence(array $parsers)
Definition: Brick.php:103
range(int $start, int $end)
Definition: Brick.php:68
-type Continuation Closure(Result<Intermediate>): Result<Intermediate> -type Parser Closure(Intermedi...
Definition: Brick.php:34
apply(Closure $parse, string $input)
Definition: Brick.php:45