UNPKG

create-expo-cljs-app

Version:

Create a react native application with Expo and Shadow-CLJS!

257 lines (236 loc) 9.09 kB
/** * @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper * @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * @license BSD-3-Clause (see LICENSE in the root directory of this source tree) */ import {assert} from '../assert'; import {DateTimeException, IllegalArgumentException} from '../errors'; import {MathUtil} from '../MathUtil'; /** * The range of valid values for a date-time field. * * All TemporalField instances have a valid range of values. * For example, the ISO day-of-month runs from 1 to somewhere between 28 and 31. * This class captures that valid range. * * It is important to be aware of the limitations of this class. * Only the minimum and maximum values are provided. * It is possible for there to be invalid values within the outer range. * For example, a weird field may have valid values of 1, 2, 4, 6, 7, thus * have a range of '1 - 7', despite that fact that values 3 and 5 are invalid. * * Instances of this class are not tied to a specific field. */ export class ValueRange { /** * * @param {!number} minSmallest * @param {!number} minLargest * @param {!number} maxSmallest * @param {!number} maxLargest * @private */ constructor(minSmallest, minLargest, maxSmallest, maxLargest) { assert(!(minSmallest > minLargest), 'Smallest minimum value \'' + minSmallest + '\' must be less than largest minimum value \'' + minLargest + '\'', IllegalArgumentException); assert(!(maxSmallest > maxLargest), 'Smallest maximum value \'' + maxSmallest + '\' must be less than largest maximum value \'' + maxLargest + '\'', IllegalArgumentException); assert(!(minLargest > maxLargest), 'Minimum value \'' + minLargest + '\' must be less than maximum value \'' + maxLargest + '\'', IllegalArgumentException); this._minSmallest = minSmallest; this._minLargest = minLargest; this._maxLargest = maxLargest; this._maxSmallest = maxSmallest; } /** * Is the value range fixed and fully known. * * For example, the ISO day-of-month runs from 1 to between 28 and 31. * Since there is uncertainty about the maximum value, the range is not fixed. * However, for the month of January, the range is always 1 to 31, thus it is fixed. * * @return {boolean} true if the set of values is fixed */ isFixed() { return this._minSmallest === this._minLargest && this._maxSmallest === this._maxLargest; } /** * * @returns {number} */ minimum(){ return this._minSmallest; } /** * * @returns {number} */ largestMinimum(){ return this._minLargest; } /** * * @returns {number} */ maximum(){ return this._maxLargest; } /** * * @returns {number} */ smallestMaximum(){ return this._maxSmallest; } /** * * @returns {boolean} */ isValidValue(value) { return (this.minimum() <= value && value <= this.maximum()); } /** * * @param {number} value * @param {TemporalField} field */ checkValidValue(value, field) { let msg; if (!this.isValidValue(value)) { if (field != null) { msg = ('Invalid value for ' + field + ' (valid values ' + (this.toString()) + '): ') + value; } else { msg = ('Invalid value (valid values ' + (this.toString()) + '): ') + value; } return assert(false, msg, DateTimeException); } } /** * Checks that the specified value is valid and fits in an `int`. * * This validates that the value is within the valid range of values and that * all valid values are within the bounds of an `int`. * The field is only used to improve the error message. * * @param {number} value - the value to check * @param {TemporalField} field - the field being checked, may be null * @return {number} the value that was passed in * @see #isValidIntValue(long) */ checkValidIntValue(value, field) { if (this.isValidIntValue(value) === false) { throw new DateTimeException('Invalid int value for ' + field + ': ' + value); } return value; } /** * Checks if the value is within the valid range and that all values * in the range fit in an `int`. * * This method combines {@link isIntValue} and {@link isValidValue}. * * @param {number} value - the value to check * @return true if the value is valid and fits in an `int` */ isValidIntValue(value) { return this.isIntValue() && this.isValidValue(value); } /** * Checks if all values in the range fit in an `int`. * * This checks that all valid values are within the bounds of an `int`. * * For example, the ISO month-of-year has values from 1 to 12, which fits in an `int`. * By comparison, ISO nano-of-day runs from 1 to 86,400,000,000,000 which does not fit in an `int`. * * This implementation uses {@link getMinimum} and {@link getMaximum}. * * @return boolean if a valid value always fits in an `int` */ isIntValue() { // should be isSafeIntegerValue return this.minimum() >= MathUtil.MIN_SAFE_INTEGER && this.maximum() <= MathUtil.MAX_SAFE_INTEGER; } /** * Checks if this range is equal to another range. * * The comparison is based on the four values, minimum, largest minimum, * smallest maximum and maximum. * Only objects of type {@link ValueRange} are compared, other types return false. * * @param {*} other - the object to check, null returns false * @return {boolean} true if this is equal to the other range */ equals(other) { if (other === this) { return true; } if (other instanceof ValueRange) { return this._minSmallest === other._minSmallest && this._minLargest === other._minLargest && this._maxSmallest === other._maxSmallest && this._maxLargest === other._maxLargest; } return false; } /** * A hash code for this range. * * @return {number} a suitable hash code */ hashCode() { return MathUtil.hashCode(this._minSmallest, this._minLargest, this._maxSmallest, this._maxLargest); } /* * Outputs this range as a String. * * The format will be '{min}/{largestMin} - {smallestMax}/{max}', * where the largestMin or smallestMax sections may be omitted, together * with associated slash, if they are the same as the min or max. * * @return {string} a string representation of this range, not null */ toString() { let str = this.minimum() + (this.minimum() !== this.largestMinimum() ? '/' + (this.largestMinimum()) : ''); str += ' - '; str += this.smallestMaximum() + (this.smallestMaximum() !== this.maximum() ? '/' + (this.maximum()) : ''); return str; } /* * called with 2 params: Obtains a fixed value range. * * This factory obtains a range where the minimum and maximum values are fixed. * For example, the ISO month-of-year always runs from 1 to 12. * * @param min the minimum value * @param max the maximum value * @return the ValueRange for min, max, not null * called with 3 params: Obtains a variable value range. * * This factory obtains a range where the minimum value is fixed and the maximum value may vary. * For example, the ISO day-of-month always starts at 1, but ends between 28 and 31. * * @param min the minimum value * @param maxSmallest the smallest maximum value * @param maxLargest the largest maximum value * @return the ValueRange for min, smallest max, largest max, not null * called with 4 params: Obtains a fully variable value range. * * This factory obtains a range where both the minimum and maximum value may vary. * * @param minSmallest the smallest minimum value * @param minLargest the largest minimum value * @param maxSmallest the smallest maximum value * @param maxLargest the largest maximum value * * @return {ValueRange} the ValueRange for smallest min, largest min, smallest max, largest max, not null */ static of() { if (arguments.length === 2) { return new ValueRange(arguments[0], arguments[0], arguments[1], arguments[1]); } else if (arguments.length === 3) { return new ValueRange(arguments[0], arguments[0], arguments[1], arguments[2]); } else if (arguments.length === 4) { return new ValueRange(arguments[0], arguments[1], arguments[2], arguments[3]); } else { return assert(false, 'Invalid number of arguments ' + arguments.length, IllegalArgumentException); } } }