Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
NamespaceGenerator
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
2 / 2
4
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 execute
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3/**
4 * @license MIT
5 * @author hazuki3417<hazuki3417@gmail.com>
6 * @copyright 2023 hazuki3417 all rights reserved.
7 */
8
9namespace Selen\PSR4\Generator;
10
11use Selen\PSR4\Constants;
12use Selen\PSR4\Generator\Result\NamespaceResult;
13use Selen\PSR4\Generator\Result\PathResult;
14use Selen\PSR4\Map;
15
16/**
17 * パスから名前空間を生成するクラスです
18 */
19class NamespaceGenerator implements Constants
20{
21    /**
22     * @var Map[] 名前空間のprefixとbase directoryのマッピング情報
23     */
24    private readonly array $maps;
25
26    public function __construct(Map ...$maps)
27    {
28        $this->maps = $maps;
29    }
30
31    /**
32     * パスから名前空間を生成します
33     *
34     * @param string $path パスを渡します
35     */
36    public function execute(string $path): Result
37    {
38        $conversionChar = $path;
39
40        // マッピング情報に基づいてパスを置換
41        foreach ($this->maps as $map) {
42            /**
43             * NOTE: 一番最初にマッチしたものを使う。
44             *       複数マッチするケースがある場合は引数の指定順を工夫すること。
45             */
46            if ($map->matchBaseDirectory($conversionChar)) {
47                $conversionChar = \str_replace(
48                    $map->baseDirectory,
49                    $map->namespacePrefix,
50                    $conversionChar
51                );
52                break;
53            }
54        }
55
56        // 拡張子を除いた名前空間に置換
57        $conversionChar = \str_replace(self::EXTENSION_PHP, '', $conversionChar);
58
59        // 区切り文字を置換(path -> namespace)
60        $conversionChar = \str_replace(self::DELIMITER_PATH, self::DELIMITER_NAMESPACE, $conversionChar);
61
62        // 区切り文字で単語に分割(名前空間)
63        $words = \explode(self::DELIMITER_NAMESPACE, $conversionChar);
64
65        $namespace = new NamespaceResult(
66            \implode(self::DELIMITER_NAMESPACE, $words),
67            \implode(self::DELIMITER_NAMESPACE, \array_slice($words, 0, -1)),
68            \array_slice($words, -1)[0]
69        );
70
71        $path = new PathResult(
72            $path,
73            \dirname($path),
74            \basename($path)
75        );
76        return new Result($namespace, $path);
77    }
78}