1: <?php declare(strict_types=1);
2:
3: namespace Salient\Console\Format;
4:
5: use Salient\Contract\Console\Format\FormatInterface as Format;
6: use Salient\Contract\Console\Format\TagAttributesInterface;
7: use Salient\Contract\Core\Immutable;
8: use Salient\Core\Concern\ImmutableTrait;
9: use Salient\Utility\Arr;
10:
11: /**
12: * @api
13: */
14: class TagFormats implements Immutable
15: {
16: use ImmutableTrait;
17:
18: /** @var array<Format::TAG_*,Format> */
19: private array $Formats = [];
20: private bool $RemoveEscapes;
21: private bool $WrapAfterFormatting;
22: private NullFormat $FallbackFormat;
23:
24: /**
25: * @api
26: */
27: public function __construct(
28: bool $removeEscapes = true,
29: bool $wrapAfterFormatting = false
30: ) {
31: $this->RemoveEscapes = $removeEscapes;
32: $this->WrapAfterFormatting = $wrapAfterFormatting;
33: $this->FallbackFormat = new NullFormat();
34: }
35:
36: /**
37: * Get an instance where escapes are removed from strings
38: *
39: * @return static
40: */
41: public function withRemoveEscapes(bool $remove = true)
42: {
43: return $this->with('RemoveEscapes', $remove);
44: }
45:
46: /**
47: * Get an instance where strings are wrapped after formatting
48: *
49: * @return static
50: */
51: public function withWrapAfterFormatting(bool $value = true)
52: {
53: return $this->with('WrapAfterFormatting', $value);
54: }
55:
56: /**
57: * Check if escapes should be removed from strings
58: */
59: public function removesEscapes(): bool
60: {
61: return $this->RemoveEscapes;
62: }
63:
64: /**
65: * Check if strings should be wrapped after formatting
66: */
67: public function wrapsAfterFormatting(): bool
68: {
69: return $this->WrapAfterFormatting;
70: }
71:
72: /**
73: * Get an instance where a format is assigned to a tag
74: *
75: * @param Format::TAG_* $tag
76: * @return static
77: */
78: public function withFormat(int $tag, Format $format)
79: {
80: return $this->with('Formats', Arr::set($this->Formats, $tag, $format));
81: }
82:
83: /**
84: * Get the format assigned to a tag
85: *
86: * @param Format::TAG_* $tag
87: */
88: public function getFormat(int $tag): Format
89: {
90: return $this->Formats[$tag] ?? $this->FallbackFormat;
91: }
92:
93: /**
94: * @internal
95: */
96: public function apply(
97: string $string,
98: TagAttributesInterface $attributes
99: ): string {
100: $tag = $attributes->getTag();
101: $format = $this->Formats[$tag] ?? $this->FallbackFormat;
102: return $format->apply($string, $attributes);
103: }
104: }
105: