Skip to content

Commit

Permalink
generate calling codes at build time
Browse files Browse the repository at this point in the history
  • Loading branch information
mledoze committed Sep 12, 2023
1 parent f41cbf2 commit 5d8d380
Show file tree
Hide file tree
Showing 14 changed files with 1,353 additions and 1,325 deletions.
500 changes: 250 additions & 250 deletions dist/countries-unescaped.json

Large diffs are not rendered by default.

500 changes: 250 additions & 250 deletions dist/countries.csv

Large diffs are not rendered by default.

500 changes: 250 additions & 250 deletions dist/countries.json

Large diffs are not rendered by default.

498 changes: 249 additions & 249 deletions dist/countries.xml

Large diffs are not rendered by default.

500 changes: 250 additions & 250 deletions dist/countries.yml

Large diffs are not rendered by default.

51 changes: 35 additions & 16 deletions src/MLD/Console/Command/ExportCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
use JsonException;
use MLD\Converter\Factory;
use MLD\Enum\ExportCommandOptions;
use MLD\Enum\Fields;
use MLD\Enum\Formats;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

use function count;

/**
Expand Down Expand Up @@ -54,28 +56,28 @@ protected function configure(): void
$this
->setDescription('Converts source country data to various output formats')
->addOption(
ExportCommandOptions::EXCLUDE_FIELD,
ExportCommandOptions::EXCLUDE_FIELD->value,
'x',
InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED,
'If set, excludes top-level field with the given name from the output. Cannot be used with --include-field',
[]
)
->addOption(
ExportCommandOptions::INCLUDE_FIELD,
ExportCommandOptions::INCLUDE_FIELD->value,
'i',
InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED,
'If set, include only these top-level fields with the given name from the output. Cannot be used with --exclude-field',
[]
Fields::values()
)
->addOption(
ExportCommandOptions::FORMAT,
ExportCommandOptions::FORMAT->value,
'f',
InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED,
'Output formats',
Formats::getAll()
Formats::values()
)
->addOption(
ExportCommandOptions::OUTPUT_DIR,
ExportCommandOptions::OUTPUT_DIR->value,
null,
InputOption::VALUE_OPTIONAL | InputOption::VALUE_REQUIRED,
'Directory where you want to put output files',
Expand All @@ -98,6 +100,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return 1;
}

$countries = $this->generateFields($countries);

$outputFields = $this->getOutputFields($input, $countries);
if ($output->isVerbose()) {
$output->writeln(sprintf('Output fields: %s', implode(',', $outputFields)));
Expand All @@ -106,7 +110,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$countries = $this->filterFields($countries, $outputFields);

$formats = $this->getFormats($input);

foreach ($formats as $format) {
if ($output->isVerbose()) {
$output->writeln(sprintf('Converting to %s', $format));
Expand Down Expand Up @@ -135,7 +138,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
*/
protected function getFormats(InputInterface $input): array
{
return $input->getOption(ExportCommandOptions::FORMAT);
return $input->getOption(ExportCommandOptions::FORMAT->value);
}

/**
Expand Down Expand Up @@ -169,9 +172,7 @@ private function filterFields(array $countries, array $outputFields): array

$flippedOutputFields = array_flip($outputFields);
return array_map(
static function ($country) use ($flippedOutputFields) {
return array_intersect_key($country, $flippedOutputFields);
},
static fn($country) => array_intersect_key($country, $flippedOutputFields),
$countries
);
}
Expand All @@ -185,8 +186,8 @@ static function ($country) use ($flippedOutputFields) {
private function getOutputFields(InputInterface $input, array $countries): array
{
$baseFields = array_keys(reset($countries));
$excludeFields = $input->getOption(ExportCommandOptions::EXCLUDE_FIELD);
$includeFields = $input->getOption(ExportCommandOptions::INCLUDE_FIELD);
$excludeFields = $input->getOption(ExportCommandOptions::EXCLUDE_FIELD->value);
$includeFields = $input->getOption(ExportCommandOptions::INCLUDE_FIELD->value);

$outputFields = $baseFields;
if (!empty($excludeFields)) {
Expand Down Expand Up @@ -252,9 +253,9 @@ private function generateFilename(string $format): string
$baseFilename = self::BASE_OUTPUT_FILENAME;

// special case for JSON unespaced
if ($format === Formats::JSON_UNESCAPED) {
if ($format === Formats::JSON_UNESCAPED->value) {
$baseFilename .= '-unescaped';
$format = Formats::JSON;
$format = Formats::JSON->value;
}

return sprintf('%s.%s', $baseFilename, $format);
Expand All @@ -266,6 +267,24 @@ private function generateFilename(string $format): string
*/
private function setOutputDirectory(InputInterface $input): void
{
$this->outputDirectory = trim($input->getOption(ExportCommandOptions::OUTPUT_DIR) ?? $this->outputDirectory);
$this->outputDirectory = trim(
$input->getOption(ExportCommandOptions::OUTPUT_DIR->value) ?? $this->outputDirectory
);
}

/**
* Generate fields that exist only at build time
*/
private function generateFields(array $countries): array
{
// generate calling codes from the "idd" property
$generateCallingCodes = static function ($country) {
$country[Fields::CALLING_CODES->value] = array_map(
static fn($suffix): string => $country[Fields::IDD->value][Fields::IDD_ROOT->value] . $suffix,
$country[Fields::IDD->value][Fields::IDD_SUFFIXES->value]
);
return $country;
};
return array_map($generateCallingCodes, $countries);
}
}
8 changes: 4 additions & 4 deletions src/MLD/Converter/AbstractJsonConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ protected function processEmptyArrays(array $countries): array
{
return array_map(
static function ($country) {
if (isset($country[Fields::LANGUAGES]) && empty($country[Fields::LANGUAGES])) {
$country[Fields::LANGUAGES] = new stdClass();
if (isset($country[Fields::LANGUAGES->value]) && empty($country[Fields::LANGUAGES->value])) {
$country[Fields::LANGUAGES->value] = new stdClass();
}

if (isset($country[Fields::NAME][Fields::NATIVE]) && empty($country[Fields::NAME][Fields::NATIVE])) {
$country[Fields::NAME][Fields::NATIVE] = new stdClass();
if (isset($country[Fields::NAME->value][Fields::NAME_NATIVE->value]) && empty($country[Fields::NAME->value][Fields::NAME_NATIVE->value])) {
$country[Fields::NAME->value][Fields::NAME_NATIVE->value] = new stdClass();
}
return $country;
},
Expand Down
4 changes: 2 additions & 2 deletions src/MLD/Converter/CsvConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ function ($country) {

private function extractCurrencyCodes(array $country): array
{
if (isset($country[Fields::CURRENCIES])) {
$country[Fields::CURRENCIES] = array_keys($country[Fields::CURRENCIES]);
if (isset($country[Fields::CURRENCIES->value])) {
$country[Fields::CURRENCIES->value] = array_keys($country[Fields::CURRENCIES->value]);
}

return $country;
Expand Down
10 changes: 5 additions & 5 deletions src/MLD/Converter/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ class Factory
public function create(string $format): ConverterInterface
{
return match ($format) {
Formats::CSV => new CsvConverter(),
Formats::JSON => new JsonConverter(),
Formats::JSON_UNESCAPED => new JsonConverterUnicode(),
Formats::XML => new XmlConverter(),
Formats::YAML => new YamlConverter(),
Formats::CSV->value => new CsvConverter(),
Formats::JSON->value => new JsonConverter(),
Formats::JSON_UNESCAPED->value => new JsonConverterUnicode(),
Formats::XML->value => new XmlConverter(),
Formats::YAML->value => new YamlConverter(),
default => throw new InvalidArgumentException(sprintf('Unsupported format %s', $format)),
};
}
Expand Down
2 changes: 1 addition & 1 deletion src/MLD/Converter/XmlConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ private function processCountry(array $country): void
$countryNode = $this->domDocument->createElement('country');
$country = $this->flatten($country);
array_walk($country, static function ($value, $key) use ($countryNode) {
$countryNode->setAttribute($key, (string) $value);
$countryNode->setAttribute($key, (string)$value);
});
$this->domDocument->documentElement->appendChild($countryNode);
}
Expand Down
14 changes: 14 additions & 0 deletions src/MLD/Enum/EnumValues.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace MLD\Enum;

trait EnumValues
{
/**
* Return the enum values
*/
public static function values(): array
{
return array_column(self::cases(), 'value');
}
}
10 changes: 5 additions & 5 deletions src/MLD/Enum/ExportCommandOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
/**
* List the available options for the export command
*/
class ExportCommandOptions
enum ExportCommandOptions: string
{

public const OUTPUT_DIR = 'output-dir';
public const INCLUDE_FIELD = 'include-field';
public const EXCLUDE_FIELD = 'exclude-field';
public const FORMAT = 'format';
case OUTPUT_DIR = 'output-dir';
case FORMAT = 'format';
case INCLUDE_FIELD = 'include-field';
case EXCLUDE_FIELD = 'exclude-field';
}
54 changes: 30 additions & 24 deletions src/MLD/Enum/Fields.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,38 @@
/**
* List of all fields in the dataset
*/
class Fields
enum Fields: string
{
public const ALT_SPELLINGS = 'altSpellings';
public const AREA = 'area';
public const BORDERS = 'borders';
public const CALLING_CODE = 'callingCode';
public const CAPITAL = 'capital';
public const CCA2 = 'cca2';
public const CCA3 = 'cca3';
public const CCN3 = 'ccn3';
public const CIOC = 'cioc';
public const CURRENCIES = 'currencies';
public const DEMONYM = 'demonym';
public const FLAG = 'flag';
public const INDEPENDENT = 'independent';
public const LANDLOCKED = 'landlocked';
public const LANGUAGES = 'languages';
public const LAT_LNG = 'latlng';
public const NAME = 'name';
public const REGION = 'region';
public const STATUS = 'status';
public const SUBREGION = 'subregion';
public const TLD = 'tld';
public const TRANSLATIONS = 'translations';
use EnumValues;

case ALT_SPELLINGS = 'altSpellings';
case AREA = 'area';
case BORDERS = 'borders';
case CALLING_CODES = 'callingCodes';
case CAPITAL = 'capital';
case CCA2 = 'cca2';
case CCA3 = 'cca3';
case CCN3 = 'ccn3';
case CIOC = 'cioc';
case CURRENCIES = 'currencies';
case DEMONYMS = 'demonyms';
case FLAG = 'flag';
case IDD = 'idd';
case INDEPENDENT = 'independent';
case LANDLOCKED = 'landlocked';
case LANGUAGES = 'languages';
case LAT_LNG = 'latlng';
case NAME = 'name';
case REGION = 'region';
case STATUS = 'status';
case SUBREGION = 'subregion';
case TLD = 'tld';
case TRANSLATIONS = 'translations';
case UN_MEMBER = 'unMember';

// Subfields
public const NATIVE = 'native';
case NAME_NATIVE = 'native';
case IDD_ROOT = 'root';
case IDD_SUFFIXES = 'suffixes';

}
27 changes: 8 additions & 19 deletions src/MLD/Enum/Formats.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,14 @@
/**
* List all output formats
*/
class Formats
enum Formats: string
{
public const CSV = 'csv';
public const JSON = 'json';
public const JSON_UNESCAPED = 'json_unescaped';
public const XML = 'xml';
public const YAML = 'yml';
use EnumValues;

case CSV = 'csv';
case JSON = 'json';
case JSON_UNESCAPED = 'json_unescaped';
case XML = 'xml';
case YAML = 'yml';

/**
* @return array
*/
public static function getAll(): array
{
return [
self::CSV,
self::JSON,
self::JSON_UNESCAPED,
self::XML,
self::YAML
];
}
}

0 comments on commit 5d8d380

Please sign in to comment.