diff --git a/php/src/app/args.php b/php/src/app/args.php index 90e24c7..3804bbc 100644 --- a/php/src/app/args.php +++ b/php/src/app/args.php @@ -2,6 +2,8 @@ namespace nulib\app; use nulib\A; +use nulib\cl; +use nulib\cv; use nulib\str; class args { @@ -10,7 +12,10 @@ class args { * - ["myArg" => $value] devient ["--my-arg", "$value"] * - ["myOpt" => true] devient ["--my-opt"] * - ["myOpt" => false] est omis - * - les autres valeurs sont prises telles quelles + * - les autres valeurs sont transformées en chaines puis ajoutée + * + * ainsi, ["myOpt" => "value", "myArg", "myBool" => true] + * devient ["--my-opt", "value", "myArg", "--my-bool"] */ static function from_array(?array $array): array { $args = []; @@ -36,4 +41,120 @@ class args { } return $args; } + + private static function tint(string $value): int { + return intval($value); + } + + private static function tbool(string $value): bool { + return boolval($value); + } + + private static function tarray(string $value): ?array { + if ($value === "") return null; + $tmparray = explode(",", $value); + $array = null; + foreach ($tmparray as $tmpvalue) { + [$tmpkey, $tmpvalue] = str::split_pair($tmpvalue); + if ($tmpvalue === null) cv::swap($tmpkey, $tmpvalue); + if ($tmpkey === null) { + $array[] = $tmpvalue; + } else { + if (str::del_suffix($tmpkey, ":int")) { + $tmpvalue = self::tint($tmpvalue); + } elseif (str::del_suffix($tmpkey, ":bool")) { + $tmpvalue = self::tbool($tmpvalue); + } + $array[$tmpkey] = $tmpvalue; + } + } + return $array; + } + + /** + * convertir une liste d'arguments de façon qu'ils soient utilisables pour un + * appel de méthode. les arguments peuvent être de la forme: + * - "name=value" + * qui est stocké dans le tableau $query ["name" => "value"] + * - "+arg" + * qui est stocké dans le tableau $query ["arg" => true] + * - "-arg" ou "~arg" + * qui est stocké dans le tableau $query ["arg" => false] + * - "array:sval,key:aval,..." + * qui devient l'argument ["sval", "key" => "aval", ...] + * - "int:value" + * qui devient l'argument intval("value") + * - "bool:value" + * qui devient l'argument boolval("value") + * - "value" + * qui devient l'argument "value" + * + * à la fin, la liste des arguments est retournée [$arguments...] + * si le tableau $query est renseigné, il est en premier dans la liste des + * arguments e.g [$query, $arguments...] + */ + static function build_method_args(?array $args): ?array { + $query = null; + $margs = []; + $args ??= []; + foreach ($args as $arg) { + [$name, $value] = str::split_pair($arg, "="); + if ($value === null) { + if (str::del_prefix($name, "+")) { + $value = true; + } elseif (str::del_prefix($name, "-") || str::del_prefix($name, "~")) { + $value = false; + } elseif (str::del_prefix($name, "int:")) { + $margs[] = self::tint($name); + continue; + } elseif (str::del_prefix($name, "bool:")) { + $margs[] = self::tbool($name); + continue; + } elseif (str::del_prefix($name, "array:")) { + if (str::del_prefix($name, "int:")) { + $map = [self::class, "tint"]; + } elseif (str::del_prefix($name, "bool:")) { + $map = [self::class, "tbool"]; + } else { + $map = null; + } + $value = self::tarray($name); + if ($map !== null) $value = array_map($map, $value); + $margs[] = $value; + continue; + } else { + $margs[] = $name; + continue; + } + } + if (str::del_suffix($name, ":int")) { + if (str::del_suffix($name, ":array")) { + $value = array_map([self::class, "tint"], self::tarray($value)); + } else { + $value = self::tint($value); + } + } elseif (str::del_suffix($name, ":bool")) { + if (str::del_suffix($name, ":array")) { + $value = array_map([self::class, "tbool"], self::tarray($value)); + } else { + $value = self::tbool($value); + } + } elseif (str::del_suffix($name, ":array")) { + $value = self::tarray($value); + if (str::del_suffix($name, ":int")) { + $value = array_map([self::class, "tint"], $value); + } elseif (str::del_suffix($name, ":bool")) { + $value = array_map([self::class, "tbool"], $value); + } + } + if (cl::has($query, $name)) { + A::ensure_array($query[$name]); + $query[$name][] = $value; + } else { + $query[$name] = $value; + } + } + if ($query !== null) array_unshift($margs, $query); + return $margs; + } } diff --git a/php/tests/app/argsTest.php b/php/tests/app/argsTest.php index 90252d9..f4f5619 100644 --- a/php/tests/app/argsTest.php +++ b/php/tests/app/argsTest.php @@ -23,4 +23,49 @@ class argsTest extends TestCase { self::assertSame(["x", "1", "2", "3", "y"], args::from_array(["x", [1, 2, 3], "y"])); } + + function testBuild_method_args() { + self::assertSame([], args::build_method_args(null)); + self::assertSame([], args::build_method_args([])); + + self::assertSame(["a"], args::build_method_args(["a"])); + self::assertSame(["a", "b"], args::build_method_args(["a", "b"])); + + self::assertSame([0], args::build_method_args(["int:0"])); + self::assertSame([42], args::build_method_args(["int:42"])); + # pour le moment, pas de tint + self::assertSame([0], args::build_method_args(["int:"])); + self::assertSame([0], args::build_method_args(["int:truc"])); + + self::assertSame([false], args::build_method_args(["bool:0"])); + self::assertSame([true], args::build_method_args(["bool:42"])); + self::assertSame([false], args::build_method_args(["bool:"])); + self::assertSame([true], args::build_method_args(["bool:truc"])); + # pour le moment, pas de tbool + self::assertSame([true], args::build_method_args(["bool:false"])); + self::assertSame([true], args::build_method_args(["bool:true"])); + + self::assertSame([["a", "b"]], args::build_method_args(["array:a,b"])); + self::assertSame([["x" => "a", "y" => "b"]], args::build_method_args(["array:x:a,y:b"])); + # pour le moment, pas de tint + self::assertSame([[0, 42, 0, 0]], args::build_method_args(["array:int:0,42,,truc"])); + self::assertSame([["x" => 0, "y" => 42]], args::build_method_args(["array:int:x:0,y:42"])); + # pour le moment, pas de tbool + self::assertSame([[false, true, false, true, true, true]], args::build_method_args(["array:bool:0,42,,truc,false,true"])); + self::assertSame([["x" => false, "y" => true]], args::build_method_args(["array:bool:x:0,y:42"])); + + self::assertSame([["a" => true]], args::build_method_args(["+a"])); + self::assertSame([["a" => false]], args::build_method_args(["-a"])); + self::assertSame([["a" => false]], args::build_method_args(["~a"])); + self::assertSame([["x" => "a"]], args::build_method_args(["x=a"])); + self::assertSame([["x" => 0]], args::build_method_args(["x:int=0"])); + self::assertSame([["x" => 42]], args::build_method_args(["x:int=42"])); + self::assertSame([["x" => false]], args::build_method_args(["x:bool=0"])); + self::assertSame([["x" => true]], args::build_method_args(["x:bool=42"])); + self::assertSame([["x" => ["a", "b"]]], args::build_method_args(["x:array=a,b"])); + self::assertSame([["x" => [0, 42]]], args::build_method_args(["x:array:int=0,42"])); + self::assertSame([["x" => [0, 42]]], args::build_method_args(["x:int:array=0,42"])); + + self::assertSame([["x" => "a", "y" => "b"], "a", "b"], args::build_method_args(["x=a", "a", "y=b", "b"])); + } }