Commit ecd30eee authored by Guillaume Perréal's avatar Guillaume Perréal
Browse files

Refactoring de Path.

Un Path est la concaténation de une ou plusieurs PathPart, dont certaines
sont des chaînes fixes et d'autres sont des paramètres.
parent 1b1ceb47
...@@ -19,63 +19,69 @@ ...@@ -19,63 +19,69 @@
namespace Irstea\NgModelGeneratorBundle\Models\Types\Operations; namespace Irstea\NgModelGeneratorBundle\Models\Types\Operations;
use Irstea\NgModelGeneratorBundle\TypescriptHelper;
/** /**
* Class PlainPath. * Class FixedPathPart.
*/ */
class PlainPath implements Path, \JsonSerializable final class FixedPathPart implements PathPart
{ {
/** @var string */ /**
private $path; * @var string
*/
private $part;
/** /**
* PlainPath constructor. * FixedPathPart constructor.
*
* @param string $path
*/ */
public function __construct(string $path) public function __construct(string $part)
{ {
$this->path = $path; $this->part = $part;
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getUsage(): string public function asTemplate(): string
{ {
return TypescriptHelper::quoteString($this->path); return $this->part;
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getParameters(): array public function asTestPattern(): string
{ {
return []; return \preg_quote($this->part, '/');
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getPattern(): string public function asCapturePattern(): string
{ {
return preg_quote($this->path, '/'); return $this->asTestPattern();
} }
/** /**
* @return Parameter|null * {@inheritdoc}
*/ */
public function getIdentifier(): ?Parameter public function getParameter(): ?Parameter
{ {
return null; return null;
} }
/** /**
* @return mixed|string * {@inheritdoc}
*/
public function isEqual(PathPart $other): bool
{
return $other instanceof self && $other->part === $this->part;
}
/**
* @return array
*/ */
public function jsonSerialize() public function jsonSerialize()
{ {
return $this->path; return \get_object_vars($this);
} }
} }
...@@ -89,15 +89,29 @@ class Parameter implements \IteratorAggregate, \JsonSerializable ...@@ -89,15 +89,29 @@ class Parameter implements \IteratorAggregate, \JsonSerializable
yield $this->type; yield $this->type;
} }
/**
* @param self $other
*
* @return bool
*/
public function isEqual(self $other): bool
{
/* @noinspection TypeUnsafeComparisonInspection */
return $other instanceof self &&
$other->name === $this->name &&
$other->optional === $this->optional &&
$other->type == $this->type;
}
/** /**
* @return array|mixed * @return array|mixed
*/ */
public function jsonSerialize() public function jsonSerialize()
{ {
return [ return [
'name' => $this->name, 'name' => $this->name,
'type' => $this->type, 'type' => $this->type,
'required' => !$this->optional, 'required' => !$this->optional,
]; ];
} }
} }
...@@ -19,87 +19,83 @@ ...@@ -19,87 +19,83 @@
namespace Irstea\NgModelGeneratorBundle\Models\Types\Operations; namespace Irstea\NgModelGeneratorBundle\Models\Types\Operations;
use Irstea\NgModelGeneratorBundle\Exceptions\DomainException;
use Irstea\NgModelGeneratorBundle\TypescriptHelper;
/** /**
* Class PathTemplate. * Class ParameterPathPart.
*/ */
class PathTemplate implements Path, \JsonSerializable final class ParameterPathPart implements PathPart
{ {
/** @var string */ /**
private $template; * @var Parameter
*/
/** @var string */ private $parameter;
private $pattern;
/** @var Parameter[] */
private $parameters = [];
/** @var string|null */ /**
private $identifierName; * @var string
*/
private $requirement;
/** /**
* PathTemplate constructor. * ParameterPathPart constructor.
* *
* @param string $template * @param Parameter $parameter
* @param string $pattern * @param string $requirement
* @param Parameter[] $parameters
* @param string|null $identifierName
*/ */
public function __construct(string $template, string $pattern, array $parameters, ?string $identifierName) public function __construct(Parameter $parameter, string $requirement = '[^/]+')
{ {
$this->template = $template; $this->parameter = $parameter;
$this->pattern = $pattern; $this->requirement = $requirement;
$this->identifierName = $identifierName; }
foreach ($parameters as $parameter) { /**
$this->parameters[$parameter->getName()] = $parameter; * {@inheritdoc}
} */
public function asTemplate(): string
{
return sprintf('${%s}', $this->parameter->getName());
}
if ($identifierName && !isset($this->parameters[$identifierName])) { /**
throw new DomainException("L'identifiant $identifierName n'est pas dans la liste des paramètres"); * {@inheritdoc}
} */
public function asTestPattern(): string
{
return $this->requirement;
} }
/** /**
* Get template. * {@inheritdoc}
*
* @return string
*/ */
public function getUsage(): string public function asCapturePattern(): string
{ {
return TypescriptHelper::quoteString($this->template, '`'); return sprintf('(%s)', $this->requirement);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getPattern(): string public function getParameter(): ?Parameter
{ {
return $this->pattern; return $this->parameter;
} }
/** /**
* Get parameters. * {@inheritdoc}
*
* @return Parameter[]
*/ */
public function getParameters(): array public function isEqual(PathPart $other): bool
{ {
return $this->parameters; return $other instanceof self && $other->parameter->isEqual($this->parameter);
} }
/** /**
* @return Parameter|null * @return \Generator
*/ */
public function getIdentifier(): ?Parameter public function getIterator()
{ {
return $this->identifierName ? $this->parameters[$this->identifierName] : null; yield $this->parameter;
} }
/** /**
* @return mixed|array * @return array
*/ */
public function jsonSerialize() public function jsonSerialize()
{ {
......
...@@ -19,28 +19,157 @@ ...@@ -19,28 +19,157 @@
namespace Irstea\NgModelGeneratorBundle\Models\Types\Operations; namespace Irstea\NgModelGeneratorBundle\Models\Types\Operations;
use Irstea\NgModelGeneratorBundle\TypescriptHelper;
/** /**
* Interface Path. * Class Path.
*/ */
interface Path final class Path
{ {
/**
* @var PathPart[]
*/
private $parts;
/**
* Path constructor.
*
* @param PathPart[] $parts
*/
public function __construct(array $parts)
{
$this->parts = $parts;
}
/**
* @return string
*/
public function getUsage(): string
{
return TypescriptHelper::quoteString(
$this->getTemplate(),
$this->hasParameters() ? '`' : "'"
);
}
/**
* @return string
*/
public function getTemplate(): string
{
return implode(
'',
array_map(
function (PathPart $part): string {
return $part->asTemplate();
},
$this->parts
)
);
}
/** /**
* @return string * @return string
*/ */
public function getUsage(): string; public function getTestPattern(): string
{
return implode(
'',
array_map(
function (PathPart $part): string {
return $part->asTestPattern();
},
$this->parts
)
);
}
/** /**
* @return string * @return string
*/ */
public function getPattern(): string; public function getCapturePattern(): string
{
return implode(
'',
array_map(
function (PathPart $part): string {
return $part->asCapturePattern();
},
$this->parts
)
);
}
/**
* @return bool
*/
public function hasParameters(): bool
{
foreach ($this->parts as $part) {
if ($part->getParameter() !== null) {
return true;
}
}
return false;
}
/** /**
* @return Parameter[] * @return Parameter[]
*/ */
public function getParameters(): array; public function getParameters(): array
{
return \array_filter(
array_map(
function (PathPart $part): ?Parameter {
return $part->getParameter();
},
$this->parts
)
);
}
/**
* @param Path $other
* @param Parameter $otherParameter
*
* @return Path
*/
public function buildUsing(Path $other, Parameter $otherParameter): Path
{
if (\count($other->parts) > \count($this->parts)) {
return $this;
}
foreach ($other->parts as $index => $part) {
if (!$this->parts[$index]->isEqual($part)) {
return $this;
}
}
if (\count($other->parts) === \count($this->parts)) {
return $other;
}
return new Path(
\array_merge(
[new ParameterPathPart($otherParameter, $other->getTestPattern())],
\array_slice($this->parts, \count($other->parts))
)
);
}
/**
* @return \Generator
*/
public function getIterator()
{
yield from $this->parts;
}
/** /**
* @return Parameter|null * @return array
*/ */
public function getIdentifier(): ?Parameter; public function jsonSerialize()
{
return \get_object_vars($this);
}
} }
<?php declare(strict_types=1);
/*
* irstea/ng-model-generator-bundle generates Typescript interfaces for Angular using api-platform metadata.
* Copyright (C) 2018 IRSTEA
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License and the GNU
* Lesser General Public License along with this program. If not, see
* <https://www.gnu.org/licenses/>.
*/
namespace Irstea\NgModelGeneratorBundle\Models\Types\Operations;
/**
* interface PathPart.
*/
interface PathPart
{
/**
* @return string
*/
public function asTemplate(): string;
/**
* @return string
*/
public function asTestPattern(): string;
/**
* @return string
*/
public function asCapturePattern(): string;
/**
* @return Parameter|null
*/
public function getParameter(): ?Parameter;
/**
* @param PathPart $other
*
* @return bool
*/
public function isEqual(PathPart $other): bool;
}
...@@ -19,15 +19,12 @@ ...@@ -19,15 +19,12 @@
namespace Irstea\NgModelGeneratorBundle; namespace Irstea\NgModelGeneratorBundle;
use Irstea\NgModelGeneratorBundle\Models\ClassName;
use Irstea\NgModelGeneratorBundle\Models\Types\BuiltinType; use Irstea\NgModelGeneratorBundle\Models\Types\BuiltinType;
use Irstea\NgModelGeneratorBundle\Models\Types\Objects\Property; use Irstea\NgModelGeneratorBundle\Models\Types\Objects\Property;
use Irstea\NgModelGeneratorBundle\Models\Types\Operations\FixedPathPart;
use Irstea\NgModelGeneratorBundle\Models\Types\Operations\Parameter; use Irstea\NgModelGeneratorBundle\Models\Types\Operations\Parameter;
use Irstea\NgModelGeneratorBundle\Models\Types\Operations\ParameterPathPart;
use Irstea\NgModelGeneratorBundle\Models\Types\Operations\Path; use Irstea\NgModelGeneratorBundle\Models\Types\Operations\Path;
use Irstea\NgModelGeneratorBundle\Models\Types\Operations\PathTemplate;
use Irstea\NgModelGeneratorBundle\Models\Types\Operations\PlainPath;
use Irstea\NgModelGeneratorBundle\Models\Types\Resources\IRI;
use Irstea\NgModelGeneratorBundle\Models\Types\Union;
/** /**
* Class PathParser. * Class PathParser.
...@@ -37,19 +34,14 @@ final class PathParser implements PathParserInterface ...@@ -37,19 +34,14 @@ final class PathParser implements PathParserInterface
/** @var Property[] */ /** @var Property[] */
private $properties; private $properties;
/** @var ClassName */
private $resource;
/** /**
* PathParser constructor. * PathParser constructor.
* *
* @param ClassName $resource
* @param Property[] $properties * @param Property[] $properties
*/ */
public function __construct(ClassName $resource, array $properties) public function __construct(array $properties)
{ {
$this->properties = $properties; $this->properties = $properties;
$this->resource = $resource;
} }
/** /**
...@@ -57,65 +49,36 @@ final class PathParser implements PathParserInterface ...@@ -57,65 +49,36 @@ final class PathParser implements PathParserInterface
*/ */
public function parse(string $path, array $requirements): Path public function parse(string $path, array $requirements): Path
{ {
$parts = preg_split('/\{(\w+)\}/', $path, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); $stringParts = preg_split('/\{(\w+)\}/', $path, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
if (\count($parts) === 1) {
return new PlainPath($parts[0]);