@schukai/monster
Version:
Monster is a simple library for creating fast, robust and lightweight websites.
170 lines (156 loc) • 3.8 kB
JavaScript
/**
* Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved.
* Node module: @schukai/monster
*
* This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
*
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
* For more information about purchasing a commercial license, please contact schukai GmbH.
*
* SPDX-License-Identifier: AGPL-3.0
*/
import { Base } from "../types/base.mjs";
import { isFunction } from "../types/is.mjs";
export { Comparator };
/**
* The comparator allows a comparison function to be abstracted.
*
* The following are some examples of the application of the class.
*
* ```
* new Comparator().lessThanOrEqual(2, 5) // ↦ true
* new Comparator().greaterThan(4, 2) // ↦ true
* new Comparator().equal(4, 4) // ↦ true
* new Comparator().equal(4, 5) // ↦ false
* ```
*
* You can also pass your own comparison function, and thus define the comparison function.
*
* ```
* new Comparator(function (a, b) {
* if (a.v === b.v) return 0;
* return a.v < b.v ? -1 : 1;
* }).equal({v: 2}, {v: 2}); // ↦ true
* ```
*
* @example /example/comparator/simple/ Simple example
* @license AGPLv3
* @since 1.3.0
*/
class Comparator extends Base {
/**
* create new comparator
*
* @param {Monster.Util~exampleCallback} [callback] Comparator callback
* @throw {TypeError} unsupported type
* @throw {TypeError} impractical comparison
*/
constructor(callback) {
super();
if (isFunction(callback)) {
this.compare = callback;
} else if (callback !== undefined) {
throw new TypeError("unsupported type");
} else {
// default compare function
/**
*
* @param {*} a
* @param {*} b
* @return {integer} -1, 0 or 1
*/
this.compare = function (a, b) {
if (typeof a !== typeof b) {
throw new TypeError("impractical comparison", "types/comparator.mjs");
}
if (a === b) {
return 0;
}
return a < b ? -1 : 1;
};
}
}
/**
* changes the order of the operators
*
* @return {Comparator}
*/
reverse() {
const original = this.compare;
this.compare = (a, b) => original(b, a);
return this;
}
/**
* Checks if two variables are equal.
*
* @param {*} a
* @param {*} b
*
* @return {boolean}
*/
equal(a, b) {
return this.compare(a, b) === 0;
}
/**
* Checks if variable `a` is greater than `b`
*
* @param {*} a
* @param {*} b
*
* @return {boolean}
*/
greaterThan(a, b) {
return this.compare(a, b) > 0;
}
/**
* Checks if variable `a` is greater than or equal to `b`
*
* @param {*} a
* @param {*} b
*
* @return {boolean}
*/
greaterThanOrEqual(a, b) {
return this.greaterThan(a, b) || this.equal(a, b);
}
/**
* Checks if variable `a` is less than or equal to `b`
*
* @param {*} a
* @param {*} b
*
* @return {boolean}
*/
lessThanOrEqual(a, b) {
return this.lessThan(a, b) || this.equal(a, b);
}
/**
* Checks if variable a is less than b
*
* @param {*} a
* @param {*} b
*
* @return {boolean}
*/
lessThan(a, b) {
return this.compare(a, b) < 0;
}
}
/**
* This is the description for the callback function used by the operator
*
* ```
* new Comparator(function (a, b) {
* if (a.v === b.v) return 0;
* return a.v < b.v ? -1 : 1;
* }).equal({v: 2}, {v: 2}); // ↦ true
* ```
*
* @callback Monster.Util~exampleCallback
* @param {*} a
* @param {*} b
* @return {integer} -1, 0 or 1
* @see Monster.Util.Comparator
*/