From 4820e9fdb42fd7a36e4ca556ecb61863b9ec4b38 Mon Sep 17 00:00:00 2001
From: Kacper Donat <kadet1090@gmail.com>
Date: Wed, 28 Feb 2018 21:50:47 +0100
Subject: [PATCH] add constant value predicate

---
 src/Predicate/AbstractPredicate.php |  6 +--
 src/Predicate/ConstantPredicate.php | 58 +++++++++++++++++++++++++++++
 src/functions.php                   | 37 ++++++++++++++++++
 3 files changed, 98 insertions(+), 3 deletions(-)
 create mode 100644 src/Predicate/ConstantPredicate.php

diff --git a/src/Predicate/AbstractPredicate.php b/src/Predicate/AbstractPredicate.php
index bccab4f..b4e937f 100644
--- a/src/Predicate/AbstractPredicate.php
+++ b/src/Predicate/AbstractPredicate.php
@@ -10,8 +10,8 @@
 namespace Kadet\Functional\Predicate;
 
 
+use function Kadet\Functional\{ all, any };
 use Kadet\Functional\Predicate;
-use function Kadet\Functional\predicate;
 
 abstract class AbstractPredicate implements Predicate
 {
@@ -23,12 +23,12 @@ abstract class AbstractPredicate implements Predicate
     public function and(...$predicate): Predicate
     {
         array_unshift($predicate, $this);
-        return new AllOfPredicate(...array_map(predicate::class, $predicate));
+        return all($predicate);
     }
 
     public function or(...$predicate): Predicate
     {
         array_unshift($predicate, $this);
-        return new AnyOfPredicate(...array_map(predicate::class, $predicate));
+        return any($predicate);
     }
 }
\ No newline at end of file
diff --git a/src/Predicate/ConstantPredicate.php b/src/Predicate/ConstantPredicate.php
new file mode 100644
index 0000000..03e6e70
--- /dev/null
+++ b/src/Predicate/ConstantPredicate.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Copyright 2018 Kacper Donat
+ *
+ * @author Kacper "Kadet" Donat <kacper@kadet.net>
+ *
+ * Full license available in separate LICENSE file
+ */
+
+namespace Kadet\Functional\Predicate;
+
+
+use function Kadet\Functional\{ all, any };
+use Kadet\Functional\Predicate;
+
+class ConstantPredicate extends AbstractPredicate
+{
+    /** @var boolean */
+    private $value;
+
+    /**
+     * ConstantPredicate constructor.
+     *
+     * @param bool $value
+     */
+    public function __construct(bool $value)
+    {
+        $this->value = $value;
+    }
+
+    public function not(): Predicate
+    {
+        return new self(!$this->value);
+    }
+
+    public function and (...$predicate): Predicate
+    {
+        if (!$this->value) {
+            return new self(false);
+        }
+
+        return all($predicate);
+    }
+
+    public function or (...$predicate): Predicate
+    {
+        if ($this->value) {
+            return new self(true);
+        }
+
+        return any($predicate);
+    }
+
+    public function __invoke(...$args): bool
+    {
+        return $this->value;
+    }
+}
\ No newline at end of file
diff --git a/src/functions.php b/src/functions.php
index d906ae7..1030922 100644
--- a/src/functions.php
+++ b/src/functions.php
@@ -2,7 +2,10 @@
 
 namespace Kadet\Functional;
 
+use Kadet\Functional\Predicate\AllOfPredicate;
+use Kadet\Functional\Predicate\AnyOfPredicate;
 use Kadet\Functional\Predicate\ClosurePredicate;
+use Kadet\Functional\Predicate\ConstantPredicate;
 
 /**
  * @param $predicate
@@ -24,3 +27,37 @@ function predicate($predicate): Predicate
     throw new \Exception();
 }
 
+function not($predicate)
+{
+    return predicate($predicate)->not();
+}
+
+function always()
+{
+    return new ConstantPredicate(true);
+}
+
+function never()
+{
+    return new ConstantPredicate(false);
+}
+
+function all(...$predicates)
+{
+    // extract array
+    if (count($predicates) === 1 && is_array($predicates[0])) {
+        $predicates = $predicates[0];
+    }
+
+    return new AllOfPredicate(...array_map(predicate::class, $predicates));
+}
+
+function any(...$predicates)
+{
+    // extract array
+    if (count($predicates) === 1 && is_array($predicates[0])) {
+        $predicates = $predicates[0];
+    }
+
+    return new AnyOfPredicate(...array_map(predicate::class, $predicates));
+}