Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
41 / 41
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
16 / 16
CRAP
100.00% covered (success)
100.00%
1 / 1
Config
100.00% covered (success)
100.00%
41 / 41
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
16 / 16
19
100.00% covered (success)
100.00%
1 / 1
 asList
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 extra
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 coercionMode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 rule
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 rules
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 coercer
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 coercers
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 message
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 messages
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 ruleParser
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 definition
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 defaultMessages
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 messageFormatter
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 resolvedRuleRegistry
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 resolvedCoercerRegistry
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 resolvedRuleParser
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Celema\Sire;
6
7use Closure;
8use ValueError;
9
10/** @internal */
11final class Config
12{
13    private bool $list = false;
14    private Extra $extra = Extra::Ignore;
15    private CoercionMode $coercionMode = CoercionMode::Coerce;
16    /** @var array<string, string> */
17    private array $messages = [];
18    private ?Contract\RuleRegistry $ruleRegistry = null;
19    /** @var array<string, Contract\Rule> */
20    private array $rules = [];
21    private ?Contract\CoercerRegistry $coercerRegistry = null;
22    /** @var array<string, Contract\Coercer> */
23    private array $coercers = [];
24    private ?Contract\RuleParser $ruleParser = null;
25
26    public function asList(bool $list): void
27    {
28        $this->list = $list;
29    }
30
31    public function extra(Extra|string $extra): void
32    {
33        if ($extra instanceof Extra) {
34            $this->extra = $extra;
35
36            return;
37        }
38
39        $this->extra = Extra::tryFrom($extra) ?? throw new ValueError(sprintf(
40            'Invalid extra mode "%s"',
41            $extra,
42        ));
43    }
44
45    public function coercionMode(CoercionMode $mode): void
46    {
47        $this->coercionMode = $mode;
48    }
49
50    public function rule(string $name, Contract\Rule $rule): void
51    {
52        $this->rules[$name] = $rule;
53    }
54
55    public function rules(Contract\RuleRegistry $registry): void
56    {
57        $this->ruleRegistry = $registry;
58        $this->rules = [];
59    }
60
61    public function coercer(string $name, Contract\Coercer $coercer): void
62    {
63        $this->coercers[$name] = $coercer;
64    }
65
66    public function coercers(Contract\CoercerRegistry $registry): void
67    {
68        $this->coercerRegistry = $registry;
69        $this->coercers = [];
70    }
71
72    public function message(string $key, string $message): void
73    {
74        $this->messages[$key] = $message;
75    }
76
77    /** @param array<string, string> $messages */
78    public function messages(array $messages): void
79    {
80        $this->messages = array_replace($this->messages, $messages);
81    }
82
83    public function ruleParser(Contract\RuleParser $parser): void
84    {
85        $this->ruleParser = $parser;
86    }
87
88    /**
89     * @param array<string, Field> $fields
90     * @param list<Closure(array<array-key, mixed>): array<array-key, mixed>> $prepareCallbacks
91     * @param list<Closure(Review): void> $reviewCallbacks
92     */
93    public function definition(
94        array $fields,
95        array $prepareCallbacks,
96        array $reviewCallbacks,
97    ): ShapeDefinition {
98        return new ShapeDefinition(
99            $this->list,
100            $this->extra,
101            $this->coercionMode,
102            $fields,
103            $this->resolvedRuleRegistry(),
104            $this->resolvedCoercerRegistry(),
105            $this->resolvedRuleParser(),
106            $this->messageFormatter(),
107            $prepareCallbacks,
108            $reviewCallbacks,
109        );
110    }
111
112    /** @return array<string, string> */
113    public function defaultMessages(): array
114    {
115        return Messages::defaults($this->resolvedRuleRegistry(), $this->resolvedCoercerRegistry());
116    }
117
118    private function messageFormatter(): MessageFormatter
119    {
120        return new MessageFormatter($this->messages);
121    }
122
123    private function resolvedRuleRegistry(): Contract\RuleRegistry
124    {
125        $this->ruleRegistry ??= RuleRegistry::withDefaults();
126
127        if ($this->rules === []) {
128            return $this->ruleRegistry;
129        }
130
131        return new RuleRegistry($this->rules, $this->ruleRegistry);
132    }
133
134    private function resolvedCoercerRegistry(): Contract\CoercerRegistry
135    {
136        $this->coercerRegistry ??= CoercerRegistry::withDefaults();
137
138        if ($this->coercers === []) {
139            return $this->coercerRegistry;
140        }
141
142        return new CoercerRegistry($this->coercers, $this->coercerRegistry);
143    }
144
145    private function resolvedRuleParser(): Contract\RuleParser
146    {
147        return $this->ruleParser ??= new RuleParser();
148    }
149}