packages/deriver/src/Deriver/Evaluator/Micro/ConfiguredEvaluator.php
1<?php
2
3declare(strict_types=1);
4
5namespace Deriver\Deriver\Evaluator\Micro;
6
7use Closure;
8use Deriver\Deriver\Evaluator\Evidence\EvidenceKind;
9use Deriver\Deriver\Evaluator\Evidence\Node;
10use Deriver\Deriver\Evaluator\Term;
11use Deriver\Exception\EvaluationContractException;
12use Override;
13use Throwable;
14
15/**
16 * Executable micro evaluator produced from public configuration.
17 * @implements MicroEvaluator<Term|null>
18 * @visibility root
19 */
20final class ConfiguredEvaluator implements MicroEvaluator
21{
22 /**
23 * @param Closure(Request): ?Term $evaluate Converted evaluation callback
24 */
25 public function __construct(
26 public readonly string $id,
27 public readonly string $version,
28 public readonly string $operation,
29 public readonly string $name,
30 private readonly Closure $evaluate,
31 public readonly int $priority = 0,
32 public readonly ?string $path = null,
33 public readonly ?int $start = null,
34 public readonly ?int $end = null,
35 ) {
36 }
37
38 /**
39 * Applies configured semantics and records only the demanded dependencies.
40 * @throws EvaluationContractException If trusted evaluation code fails
41 */
42 #[Override]
43 public function evaluate(Request $request): ?Term
44 {
45 $operation = $request->operation();
46 $source = $request->source();
47 if ($operation !== $this->operation || $request->name() !== $this->name || $this->path !== null && $this->path !== $source->path || $this->start !== null && $this->start !== $source->start || $this->end !== null && $this->end !== $source->end) {
48 return null;
49 }
50 try {
51 $result = ($this->evaluate)($request);
52 } catch (Throwable $error) {
53 throw new EvaluationContractException($this->id . ': ' . $error->getMessage(), previous: $error);
54 }
55 if ($result === null) {
56 return null;
57 }
58 $context = $request->engine->context;
59 $context->evaluatorApplications++;
60 $evidence = new Node(EvidenceKind::EvaluatorApplication, $context->provenance->inputs($request->inputs()), $source, ['id' => $this->id, 'version' => $this->version, 'operation' => $this->operation, 'name' => $this->name]);
61 return (new \Deriver\Deriver\Evaluator\Enumeration\Choices($context->provenance))->map($result, fn (Term $value): Term => $context->provenance->attach($value, $evidence));
62 }
63
64}
65