Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
Jephté Clain | e71693fae3 |
|
@ -1,14 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PhpTestFrameworkVersionCache">
|
||||
<tools_cache>
|
||||
<tool tool_name="PHPUnit">
|
||||
<cache>
|
||||
<versions>
|
||||
<info id="Local/vendor/autoload.php" version="9.6.22" />
|
||||
</versions>
|
||||
</cache>
|
||||
</tool>
|
||||
</tools_cache>
|
||||
</component>
|
||||
</project>
|
|
@ -4,5 +4,5 @@
|
|||
RUNPHP=
|
||||
|
||||
# Si RUNPHP n'est pas défini, les variables suivantes peuvent être définies
|
||||
DIST=d11
|
||||
DIST=d12
|
||||
#REGISTRY=pubdocker.univ-reunion.fr
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
#!/usr/bin/php
|
||||
<?php
|
||||
require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
use nulib\tools\DumpserApp;
|
||||
|
||||
DumpserApp::run();
|
|
@ -27,13 +27,13 @@
|
|||
}
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4"
|
||||
"php": "^8.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"nulib/php": "^7.4-dev",
|
||||
"nulib/spout": "^7.4-dev",
|
||||
"nulib/phpss": "^7.4-dev",
|
||||
"nulib/tests": "^7.4",
|
||||
"nulib/php": "^8.2-dev",
|
||||
"nulib/spout": "^8.2-dev",
|
||||
"nulib/phpss": "^8.2-dev",
|
||||
"nulib/tests": "^8.2",
|
||||
"ext-posix": "*",
|
||||
"ext-pcntl": "*",
|
||||
"ext-fileinfo": "*",
|
||||
|
@ -80,13 +80,12 @@
|
|||
}
|
||||
},
|
||||
"bin": [
|
||||
"bin/dumpser.php",
|
||||
"bin/csv2xlsx.php",
|
||||
"nur_bin/compctl.php",
|
||||
"nur_bin/compdep.php",
|
||||
"nur_bin/datectl.php",
|
||||
"nur_bin/fsvdiff.php",
|
||||
"nur_bin/cachectl.php",
|
||||
"nur_bin/dumpser.php",
|
||||
"nur_bin/ldap-delete.php",
|
||||
"nur_bin/ldap-get-infos.php",
|
||||
"nur_bin/ldap-search.php",
|
||||
|
|
|
@ -4,88 +4,9 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "75bc483e6daffdf3e962197c49841ce9",
|
||||
"content-hash": "90b972256fe0b784ba158cecdff7edaf",
|
||||
"packages": [],
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "composer/pcre",
|
||||
"version": "3.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/pcre.git",
|
||||
"reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
|
||||
"reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"phpstan/phpstan": "<1.11.10"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^1.12 || ^2",
|
||||
"phpstan/phpstan-strict-rules": "^1 || ^2",
|
||||
"phpunit/phpunit": "^8 || ^9"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"phpstan": {
|
||||
"includes": [
|
||||
"extension.neon"
|
||||
]
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-main": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Composer\\Pcre\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
}
|
||||
],
|
||||
"description": "PCRE wrapping library that offers type-safe preg_* replacements.",
|
||||
"keywords": [
|
||||
"PCRE",
|
||||
"preg",
|
||||
"regex",
|
||||
"regular expression"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/composer/pcre/issues",
|
||||
"source": "https://github.com/composer/pcre/tree/3.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://packagist.com",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/composer",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-11-12T16:29:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/instantiator",
|
||||
"version": "1.5.0",
|
||||
|
@ -585,11 +506,11 @@
|
|||
},
|
||||
{
|
||||
"name": "nulib/php",
|
||||
"version": "dev-php74",
|
||||
"version": "dev-master",
|
||||
"dist": {
|
||||
"type": "path",
|
||||
"url": "../nulib",
|
||||
"reference": "de3b84441d2b588475b4d6d74bffdc487e333034"
|
||||
"reference": "0dfb30d395c0516ba14ef3d9eb22e408bfd93d80"
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
|
@ -600,12 +521,12 @@
|
|||
"ext-curl": "*",
|
||||
"ext-pcntl": "*",
|
||||
"ext-posix": "*",
|
||||
"nulib/tests": "^7.4"
|
||||
"nulib/tests": "7.4"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-php74": "7.4.x-dev",
|
||||
"dev-master": "7.4.x-dev",
|
||||
"dev-php82": "8.2.x-dev"
|
||||
}
|
||||
},
|
||||
|
@ -632,11 +553,11 @@
|
|||
},
|
||||
{
|
||||
"name": "nulib/phpss",
|
||||
"version": "dev-php74",
|
||||
"version": "dev-master",
|
||||
"dist": {
|
||||
"type": "path",
|
||||
"url": "../nulib-phpss",
|
||||
"reference": "b950bb7718fa0fe48850fd6b2d71f7015e144bf1"
|
||||
"reference": "df05afda07f5973e55db4568fac5a9659ab38e76"
|
||||
},
|
||||
"require": {
|
||||
"nulib/php": "^7.4-dev",
|
||||
|
@ -649,7 +570,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-php74": "7.4.x-dev",
|
||||
"dev-master": "7.4.x-dev",
|
||||
"dev-php82": "8.2.x-dev"
|
||||
}
|
||||
},
|
||||
|
@ -676,11 +597,11 @@
|
|||
},
|
||||
{
|
||||
"name": "nulib/spout",
|
||||
"version": "dev-php74",
|
||||
"version": "dev-master",
|
||||
"dist": {
|
||||
"type": "path",
|
||||
"url": "../nulib-spout",
|
||||
"reference": "967319ff0b29b370f4345e748a5df7a63a66cea6"
|
||||
"reference": "a9df7e7c30805ea9a138ea6d07a5b4aff5793ce6"
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
|
@ -704,13 +625,13 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-php74": "7.4.x-dev",
|
||||
"dev-master": "7.4.x-dev",
|
||||
"dev-php82": "8.2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"nulib\\": "src",
|
||||
"nulib\\ext\\": "src",
|
||||
"OpenSpout\\": "upstream-3.x/src"
|
||||
}
|
||||
},
|
||||
|
@ -736,7 +657,7 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://git.univ-reunion.fr/sda-php/nulib-tests.git",
|
||||
"reference": "a8541304eeddf696040e65792f45308d1d292aed"
|
||||
"reference": "6ce8257560b42e8fb3eea03eba84d3877c9648ca"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.3",
|
||||
|
@ -760,7 +681,7 @@
|
|||
}
|
||||
],
|
||||
"description": "fonctions et classes pour les tests",
|
||||
"time": "2025-01-30T14:12:43+00:00"
|
||||
"time": "2024-03-26T10:56:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/manifest",
|
||||
|
@ -882,20 +803,19 @@
|
|||
},
|
||||
{
|
||||
"name": "phpoffice/phpspreadsheet",
|
||||
"version": "1.29.9",
|
||||
"version": "1.29.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
|
||||
"reference": "ffb47b639649fc9c8a6fa67977a27b756592ed85"
|
||||
"reference": "089ffdfc04b5fcf25a3503d81a4e589f247e20e3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/ffb47b639649fc9c8a6fa67977a27b756592ed85",
|
||||
"reference": "ffb47b639649fc9c8a6fa67977a27b756592ed85",
|
||||
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/089ffdfc04b5fcf25a3503d81a4e589f247e20e3",
|
||||
"reference": "089ffdfc04b5fcf25a3503d81a4e589f247e20e3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer/pcre": "^3.3",
|
||||
"ext-ctype": "*",
|
||||
"ext-dom": "*",
|
||||
"ext-fileinfo": "*",
|
||||
|
@ -982,9 +902,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
|
||||
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.29.9"
|
||||
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.29.8"
|
||||
},
|
||||
"time": "2025-01-26T04:55:00+00:00"
|
||||
"time": "2025-01-12T03:16:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
__uaddpath "@@dest@@/bin:@@dest@@/nur_bin" PATH
|
||||
__uaddpath "@@dest@@/nur_bin" PATH
|
||||
|
|
|
@ -5,7 +5,6 @@ use ArrayAccess;
|
|||
use Countable;
|
||||
use Exception;
|
||||
use Generator;
|
||||
use nulib\file\Stream;
|
||||
use nur\A;
|
||||
use nur\b\coll\TBaseArray;
|
||||
use nur\b\IllegalAccessException;
|
||||
|
@ -105,7 +104,6 @@ abstract class FileCachedValue extends Parametrable implements ArrayAccess, Coun
|
|||
|
||||
/** désérialiser la données depuis le contenu spécifié */
|
||||
protected function unserialize(string $contents) {
|
||||
$contents = Stream::nursery_compat_verifix($contents);
|
||||
return unserialize($contents);
|
||||
}
|
||||
|
||||
|
@ -150,7 +148,7 @@ abstract class FileCachedValue extends Parametrable implements ArrayAccess, Coun
|
|||
}
|
||||
|
||||
protected function loadInfos(): array {
|
||||
[$tstart, $duration] = $this->unserialize(fgets($this->fp));
|
||||
[$tstart, $duration] = unserialize(fgets($this->fp));
|
||||
if (is_int($tstart)) {
|
||||
$tstart = new DateTime($tstart);
|
||||
$duration = new Delay($duration, $tstart);
|
||||
|
|
|
@ -1,255 +0,0 @@
|
|||
<?php
|
||||
namespace nur\sery\wip\php\coll;
|
||||
|
||||
use Iterator;
|
||||
use nulib\cl;
|
||||
use nulib\php\func;
|
||||
use nur\sery\wip\php\iter;
|
||||
use Traversable;
|
||||
|
||||
/**
|
||||
* Class Cursor: parcours des lignes itérable
|
||||
*
|
||||
* @property-read array|null $value alias pour $row
|
||||
* @property-read iterable|null $rows la source des lignes
|
||||
*/
|
||||
class Cursor implements Iterator {
|
||||
const PARAMS_SCHEMA = [
|
||||
"rows" => ["?iterable"],
|
||||
"rows_func" => ["?callable"],
|
||||
"cols" => ["?array"],
|
||||
"cols_func" => ["?callable"],
|
||||
"map" => ["?array"],
|
||||
"map_func" => ["?callable"],
|
||||
"filter" => ["?array"],
|
||||
"filter_func" => ["?callable"],
|
||||
];
|
||||
|
||||
/**
|
||||
* mapper le tableau source $row selon les règles suivantes illustrées dans
|
||||
* l'exemple suivant:
|
||||
* si
|
||||
* $map = ["a", "b" => "x", "c" => function() { return "y"; }, "d" => null]
|
||||
* alors retourner le tableau
|
||||
* ["a" => $row["a"], "b" => $row["x"], "c" => "y", "d" => null]
|
||||
*/
|
||||
private static function map_row(array $row, ?array $map): array {
|
||||
if ($map === null) return $row;
|
||||
$index = 0;
|
||||
$mapped = [];
|
||||
foreach ($map as $key => $value) {
|
||||
if ($key === $index) {
|
||||
$index++;
|
||||
if ($value === null) $mapped[] = null;
|
||||
else $mapped[$value] = cl::get($row, $value);
|
||||
} elseif (is_callable($value)) {
|
||||
$func = func::with($value);
|
||||
$value = cl::get($row, $key);
|
||||
$mapped[$key] = $func->invoke([$value, $key, $row]);
|
||||
} else {
|
||||
if ($value === null) $mapped[$key] = null;
|
||||
else $mapped[$key] = cl::get($row, $key);
|
||||
}
|
||||
}
|
||||
return $mapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* tester si $row satisfait les conditions de $filter
|
||||
* - $filter est un scalaire, le transformer en [$filter]
|
||||
* - sinon $filter doit être un tableau de scalaires
|
||||
*
|
||||
* les règles des conditions sont les suivantes:
|
||||
* - une valeur séquentielle $key est équivalente à la valeur associative
|
||||
* $key => true
|
||||
* - une valeur associative $key => bool indique que la clé correspondante ne
|
||||
* doit pas (resp. doit) exister selon que bool vaut false (resp. true)
|
||||
* - une valeur associative $key => $value indique que la clé correspondante
|
||||
* doit exiter avec la valeur spécifiée
|
||||
*/
|
||||
private static function filter_row(array $row, $filter): bool {
|
||||
if ($filter === null) return false;
|
||||
if (!is_array($filter)) $filter = [$filter];
|
||||
if (!$filter) return false;
|
||||
|
||||
$index = 0;
|
||||
foreach ($filter as $key => $value) {
|
||||
if ($key === $index) {
|
||||
$index++;
|
||||
if (!array_key_exists($value, $row)) return false;
|
||||
} elseif (is_bool($value)) {
|
||||
if ($value) {
|
||||
if (!array_key_exists($value, $row)) return false;
|
||||
} else {
|
||||
if (array_key_exists($value, $row)) return false;
|
||||
}
|
||||
} else {
|
||||
if (!array_key_exists($value, $row)) return false;
|
||||
if ($row[$key] !== $value) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function __construct(?iterable $rows=null, ?array $params=null) {
|
||||
if ($rows !== null) $params["rows"] = $rows;
|
||||
|
||||
$rows = $params["rows"] ?? null;
|
||||
$rowsGenerator = null;
|
||||
$rowsFunc = $params["rows_func"] ?? null;
|
||||
if ($rowsFunc !== null) {
|
||||
if ($rowsFunc instanceof Traversable) {
|
||||
$rowsGenerator = $rowsFunc;
|
||||
$rowsFunc = null;
|
||||
} else {
|
||||
$rowsFunc = func::with($rowsFunc, [$rows]);
|
||||
}
|
||||
} elseif ($rows instanceof Traversable) {
|
||||
$rowsGenerator = $rows;
|
||||
} else {
|
||||
$rowsFunc = func::with(function() use ($rows) {
|
||||
return $rows;
|
||||
});
|
||||
}
|
||||
$this->rowsGenerator = $rowsGenerator;
|
||||
$this->rowsFunc = $rowsFunc;
|
||||
|
||||
$map = $params["map"] ?? null;
|
||||
$mapFunc = $params["map_func"] ?? null;
|
||||
if ($mapFunc !== null) {
|
||||
$mapFunc = func::with($mapFunc);
|
||||
} elseif ($map !== null) {
|
||||
$mapFunc = func::with(function(array $row) use ($map) {
|
||||
return self::map_row($row, $map);
|
||||
});
|
||||
}
|
||||
$this->mapFunc = $mapFunc;
|
||||
|
||||
$filter = $params["filter"] ?? null;
|
||||
$filterFunc = $params["filter_func"] ?? null;
|
||||
if ($filterFunc !== null) {
|
||||
$filterFunc = func::with($filterFunc);
|
||||
} elseif ($filter !== null) {
|
||||
$filterFunc = func::with(function(array $row) use ($filter) {
|
||||
return self::filter_row($row, $filter);
|
||||
});
|
||||
}
|
||||
$this->filterFunc = $filterFunc;
|
||||
}
|
||||
|
||||
/** un générateur de lignes */
|
||||
private ?Traversable $rowsGenerator;
|
||||
|
||||
/** une fonction de signature <code>function(Cursor):?iterable</code> */
|
||||
private ?func $rowsFunc;
|
||||
|
||||
/** une fonction de signature <code>function(Cursor):?array</code> */
|
||||
private ?func $colsFunc;
|
||||
|
||||
/** une fonction de signature <code>function(Cursor):?array</code> */
|
||||
private ?func $mapFunc;
|
||||
|
||||
/** une fonction de signature <code>function(Cursor):bool</code> */
|
||||
private ?func $filterFunc;
|
||||
|
||||
protected ?iterable $rows;
|
||||
|
||||
public ?array $cols;
|
||||
|
||||
public int $index;
|
||||
|
||||
public int $origIndex;
|
||||
|
||||
public $key;
|
||||
|
||||
public $raw;
|
||||
|
||||
public ?array $row;
|
||||
|
||||
function __get($name) {
|
||||
if ($name === "value") return $this->row;
|
||||
elseif ($name == "rows") return $this->rows;
|
||||
trigger_error("Undefined property $name");
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function filter(): bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function map(): ?array {
|
||||
return $this->row;
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
# Iterator
|
||||
|
||||
function rewind() {
|
||||
$this->index = 0;
|
||||
$this->origIndex = 0;
|
||||
$this->key = null;
|
||||
$this->raw = null;
|
||||
$this->row = null;
|
||||
if ($this->rowsGenerator !== null) {
|
||||
$this->rows = $this->rowsGenerator;
|
||||
$this->rows->rewind();
|
||||
} else {
|
||||
$this->rows = $this->rowsFunc->invoke();
|
||||
}
|
||||
}
|
||||
|
||||
function valid() {
|
||||
$filter = $this->filterFunc;
|
||||
$map = $this->mapFunc;
|
||||
while ($valid = iter::valid($this->rows)) {
|
||||
$this->raw = iter::current($this->rows, $this->key);
|
||||
$this->key ??= $this->origIndex;
|
||||
$this->row = cl::withn($this->raw);
|
||||
if ($filter === null) $filtered = $this->filter();
|
||||
else $filtered = $filter->invoke([$this]);
|
||||
if (!$filtered) {
|
||||
if ($map === null) $this->row = $this->map();
|
||||
else $this->row = $map->invoke([$this]);
|
||||
break;
|
||||
} else {
|
||||
iter::next($this->rows);
|
||||
$this->origIndex++;
|
||||
}
|
||||
}
|
||||
if (!$valid) {
|
||||
iter::close($this->rows);
|
||||
$this->rows = null;
|
||||
$this->index = -1;
|
||||
$this->origIndex = -1;
|
||||
$this->key = null;
|
||||
$this->raw = null;
|
||||
$this->row = null;
|
||||
}
|
||||
return $valid;
|
||||
}
|
||||
|
||||
function current() {
|
||||
return $this->row;
|
||||
}
|
||||
|
||||
function key() {
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
function next() {
|
||||
iter::next($this->rows);
|
||||
$this->index++;
|
||||
$this->origIndex++;
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
|
||||
function each(callable $func): void {
|
||||
$func = func::with($func);
|
||||
$this->rewind();
|
||||
while ($this->valid()) {
|
||||
$func->invoke([$this]);
|
||||
$this->next();
|
||||
}
|
||||
}
|
||||
}
|
169
src/php/iter.php
169
src/php/iter.php
|
@ -1,169 +0,0 @@
|
|||
<?php # -*- coding: utf-8 mode: php -*- vim:sw=2:sts=2:et:ai:si:sta:fenc=utf-8
|
||||
namespace nur\sery\wip\php;
|
||||
|
||||
use Exception;
|
||||
use Generator;
|
||||
use Iterator;
|
||||
use IteratorAggregate;
|
||||
use nulib\php\ICloseable;
|
||||
use nulib\StopException;
|
||||
use nulib\ValueException;
|
||||
use Traversable;
|
||||
|
||||
/**
|
||||
* Class iter: gestion des itérateurs
|
||||
*/
|
||||
class iter {
|
||||
private static function unexpected_type($object): ValueException {
|
||||
return ValueException::invalid_type($object, "iterable");
|
||||
}
|
||||
|
||||
/**
|
||||
* fermer "proprement" un itérateur ou un générateur. retourner true en cas de
|
||||
* succès, ou false si c'est un générateur et qu'il ne supporte pas l'arrêt
|
||||
* avec StopException (la valeur de retour n'est alors pas disponible)
|
||||
*/
|
||||
static function close($it): bool {
|
||||
if ($it instanceof ICloseable) {
|
||||
$it->close();
|
||||
return true;
|
||||
} elseif ($it instanceof Generator) {
|
||||
try {
|
||||
$it->throw(new StopException());
|
||||
return true;
|
||||
} catch (StopException $e) {
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* retourner la première valeur du tableau, de l'itérateur ou de l'instance
|
||||
* de Traversable, ou $default si aucun élément n'est trouvé.
|
||||
*/
|
||||
static final function first($values, $default=null) {
|
||||
if ($values instanceof IteratorAggregate) $values = $values->getIterator();
|
||||
if ($values instanceof Iterator) {
|
||||
try {
|
||||
$values->rewind();
|
||||
$value = $values->valid()? $values->current(): $default;
|
||||
} finally {
|
||||
self::close($values);
|
||||
}
|
||||
} elseif (is_array($values) || $values instanceof Traversable) {
|
||||
$value = $default;
|
||||
foreach ($values as $value) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
throw self::unexpected_type($values);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* retourner la première clé du tableau, de l'itérateur ou de l'instance
|
||||
* de Traversable, ou $default si aucun élément n'est trouvé.
|
||||
*/
|
||||
static final function first_key($values, $default=null) {
|
||||
if ($values instanceof IteratorAggregate) $values = $values->getIterator();
|
||||
if ($values instanceof Iterator) {
|
||||
try {
|
||||
$values->rewind();
|
||||
$key = $values->valid()? $values->key(): $default;
|
||||
} finally {
|
||||
self::close($values);
|
||||
}
|
||||
} elseif (is_array($values) || $values instanceof Traversable) {
|
||||
$key = $default;
|
||||
foreach ($values as $key => $ignored) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
throw self::unexpected_type($values);
|
||||
}
|
||||
return $key;
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
# outils pour gérer de façon générique des instances de {@link Iterator} ou
|
||||
# des arrays
|
||||
|
||||
/**
|
||||
* @param $it ?iterable|array
|
||||
* @return bool true si l'itérateur ou le tableau ont pu être réinitialisés
|
||||
*/
|
||||
static function rewind(&$it, ?Exception &$exception=null): bool {
|
||||
if ($it instanceof Iterator) {
|
||||
try {
|
||||
$exception = null;
|
||||
$it->rewind();
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
$exception = $e;
|
||||
}
|
||||
} elseif ($it !== null) {
|
||||
reset($it);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $it ?iterable|array
|
||||
*/
|
||||
static function valid($it): bool {
|
||||
if ($it instanceof Iterator) {
|
||||
return $it->valid();
|
||||
} elseif ($it !== null) {
|
||||
return key($it) !== null;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $it ?iterable|array
|
||||
*/
|
||||
static function current($it, &$key=null) {
|
||||
if ($it instanceof Iterator) {
|
||||
$key = $it->key();
|
||||
return $it->current();
|
||||
} elseif ($it !== null) {
|
||||
$key = key($it);
|
||||
return current($it);
|
||||
} else {
|
||||
$key = null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $it ?iterable|array
|
||||
*/
|
||||
static function next(&$it, ?Exception &$exception=null): void {
|
||||
if ($it instanceof Iterator) {
|
||||
try {
|
||||
$exception = null;
|
||||
$it->next();
|
||||
} catch (Exception $e) {
|
||||
$exception = $e;
|
||||
}
|
||||
} elseif ($it !== null) {
|
||||
next($it);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* obtenir la valeur de retour si $it est un générateur terminé, ou null sinon
|
||||
*/
|
||||
static function get_return($it) {
|
||||
if ($it instanceof Generator) {
|
||||
try {
|
||||
return $it->getReturn();
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
namespace nulib\tools;
|
||||
|
||||
use nulib\app\cli\Application;
|
||||
use nulib\ext\yaml;
|
||||
use nulib\file\SharedFile;
|
||||
use nulib\output\msg;
|
||||
|
||||
class DumpserApp extends Application {
|
||||
const ARGS = [
|
||||
"merge" => parent::ARGS,
|
||||
"purpose" => "afficher des données sérialisées",
|
||||
];
|
||||
|
||||
protected $args;
|
||||
|
||||
function main() {
|
||||
$files = [];
|
||||
foreach ($this->args as $arg) {
|
||||
if (is_file($arg)) {
|
||||
$files[] = $arg;
|
||||
} else {
|
||||
msg::warning("$arg: fichier invalide ou introuvable");
|
||||
}
|
||||
}
|
||||
$showSection = count($files) > 1;
|
||||
foreach ($files as $file) {
|
||||
if ($showSection) msg::section($file);
|
||||
$sfile = new SharedFile($file);
|
||||
yaml::dump($sfile->unserialize());
|
||||
}
|
||||
}
|
||||
}{
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
<?php
|
||||
namespace nur\sery\wip\php\coll;
|
||||
|
||||
use Exception;
|
||||
use nulib\cl;
|
||||
use nulib\output\msg;
|
||||
use nulib\output\std\StdMessenger;
|
||||
use nulib\tests\TestCase;
|
||||
use TypeError;
|
||||
|
||||
class CursorTest extends TestCase {
|
||||
protected function setUp(): void {
|
||||
msg::set_messenger(new StdMessenger());
|
||||
}
|
||||
|
||||
const SCALARS = [0, 1, 2, 3, 4];
|
||||
|
||||
function generator() {
|
||||
yield from self::SCALARS;
|
||||
}
|
||||
|
||||
function testVanilla() {
|
||||
$c = new Cursor(self::SCALARS);
|
||||
self::assertSame([[0], [1], [2], [3], [4]], cl::all($c));
|
||||
self::assertSame([[0], [1], [2], [3], [4]], cl::all($c));
|
||||
|
||||
$c = new Cursor($this->generator());
|
||||
self::assertSame([[0], [1], [2], [3], [4]], cl::all($c));
|
||||
self::assertException(Exception::class, function() use ($c) {
|
||||
// pas possible de rewind un générateur
|
||||
return cl::all($c);
|
||||
});
|
||||
|
||||
$c = new Cursor(null, [
|
||||
"rows" => function() {
|
||||
return self::SCALARS;
|
||||
},
|
||||
]);
|
||||
self::assertError(TypeError::class, function() use ($c) {
|
||||
// rows doit être un iterable, pas une fonction
|
||||
return cl::all($c);
|
||||
});
|
||||
|
||||
$c = new Cursor(null, [
|
||||
"rows_func" => function() {
|
||||
return self::SCALARS;
|
||||
},
|
||||
]);
|
||||
self::assertSame([[0], [1], [2], [3], [4]], cl::all($c));
|
||||
self::assertSame([[0], [1], [2], [3], [4]], cl::all($c));
|
||||
|
||||
$c = new Cursor(null, [
|
||||
"rows_func" => $this->generator(),
|
||||
]);
|
||||
self::assertSame([[0], [1], [2], [3], [4]], cl::all($c));
|
||||
self::assertException(Exception::class, function() use ($c) {
|
||||
// pas possible de rewind un générateur
|
||||
return cl::all($c);
|
||||
});
|
||||
|
||||
$c = new Cursor(null, [
|
||||
"rows_func" => function() {
|
||||
yield from self::SCALARS;
|
||||
},
|
||||
]);
|
||||
self::assertSame([[0], [1], [2], [3], [4]], cl::all($c));
|
||||
self::assertSame([[0], [1], [2], [3], [4]], cl::all($c));
|
||||
}
|
||||
|
||||
function testMap() {
|
||||
$c = new Cursor(self::SCALARS, [
|
||||
"map_func" => function(Cursor $c) {
|
||||
return [$c->raw + 1];
|
||||
},
|
||||
]);
|
||||
self::assertSame([[1], [2], [3], [4], [5]], cl::all($c));
|
||||
}
|
||||
|
||||
function testFilter() {
|
||||
$c = new Cursor(self::SCALARS, [
|
||||
"filter_func" => function(Cursor $c) {
|
||||
return $c->raw % 2 == 0;
|
||||
},
|
||||
]);
|
||||
self::assertSame([[1], [3]], cl::all($c));
|
||||
}
|
||||
|
||||
function testEach() {
|
||||
$c = new Cursor(self::SCALARS, [
|
||||
"filter_func" => function(Cursor $c) {
|
||||
return $c->raw % 2 == 0;
|
||||
},
|
||||
"map_func" => function(Cursor $c) {
|
||||
return [$c->raw + 1];
|
||||
},
|
||||
]);
|
||||
$xs = [];
|
||||
$xitems = [];
|
||||
$oxs = [];
|
||||
$kitems = [];
|
||||
$c->each(function(Cursor $c) use (&$xs, &$xitems, &$oxs, &$kitems) {
|
||||
$xs[] = $c->index;
|
||||
$oxs[] = $c->origIndex;
|
||||
$xitems[$c->index] = $c->row[0];
|
||||
$kitems[$c->key] = $c->row[0];
|
||||
});
|
||||
self::assertSame([0, 1], $xs);
|
||||
self::assertSame([2, 4], $xitems);
|
||||
self::assertSame([1, 3], $oxs);
|
||||
self::assertSame([1 => 2, 3 => 4], $kitems);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue