source: trip-planner-front/node_modules/schema-utils/dist/util/Range.js@ ceaed42

Last change on this file since ceaed42 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 4.0 KB
Line 
1"use strict";
2
3/**
4 * @typedef {[number, boolean]} RangeValue
5 */
6
7/**
8 * @callback RangeValueCallback
9 * @param {RangeValue} rangeValue
10 * @returns {boolean}
11 */
12class Range {
13 /**
14 * @param {"left" | "right"} side
15 * @param {boolean} exclusive
16 * @returns {">" | ">=" | "<" | "<="}
17 */
18 static getOperator(side, exclusive) {
19 if (side === 'left') {
20 return exclusive ? '>' : '>=';
21 }
22
23 return exclusive ? '<' : '<=';
24 }
25 /**
26 * @param {number} value
27 * @param {boolean} logic is not logic applied
28 * @param {boolean} exclusive is range exclusive
29 * @returns {string}
30 */
31
32
33 static formatRight(value, logic, exclusive) {
34 if (logic === false) {
35 return Range.formatLeft(value, !logic, !exclusive);
36 }
37
38 return `should be ${Range.getOperator('right', exclusive)} ${value}`;
39 }
40 /**
41 * @param {number} value
42 * @param {boolean} logic is not logic applied
43 * @param {boolean} exclusive is range exclusive
44 * @returns {string}
45 */
46
47
48 static formatLeft(value, logic, exclusive) {
49 if (logic === false) {
50 return Range.formatRight(value, !logic, !exclusive);
51 }
52
53 return `should be ${Range.getOperator('left', exclusive)} ${value}`;
54 }
55 /**
56 * @param {number} start left side value
57 * @param {number} end right side value
58 * @param {boolean} startExclusive is range exclusive from left side
59 * @param {boolean} endExclusive is range exclusive from right side
60 * @param {boolean} logic is not logic applied
61 * @returns {string}
62 */
63
64
65 static formatRange(start, end, startExclusive, endExclusive, logic) {
66 let result = 'should be';
67 result += ` ${Range.getOperator(logic ? 'left' : 'right', logic ? startExclusive : !startExclusive)} ${start} `;
68 result += logic ? 'and' : 'or';
69 result += ` ${Range.getOperator(logic ? 'right' : 'left', logic ? endExclusive : !endExclusive)} ${end}`;
70 return result;
71 }
72 /**
73 * @param {Array<RangeValue>} values
74 * @param {boolean} logic is not logic applied
75 * @return {RangeValue} computed value and it's exclusive flag
76 */
77
78
79 static getRangeValue(values, logic) {
80 let minMax = logic ? Infinity : -Infinity;
81 let j = -1;
82 const predicate = logic ?
83 /** @type {RangeValueCallback} */
84 ([value]) => value <= minMax :
85 /** @type {RangeValueCallback} */
86 ([value]) => value >= minMax;
87
88 for (let i = 0; i < values.length; i++) {
89 if (predicate(values[i])) {
90 [minMax] = values[i];
91 j = i;
92 }
93 }
94
95 if (j > -1) {
96 return values[j];
97 }
98
99 return [Infinity, true];
100 }
101
102 constructor() {
103 /** @type {Array<RangeValue>} */
104 this._left = [];
105 /** @type {Array<RangeValue>} */
106
107 this._right = [];
108 }
109 /**
110 * @param {number} value
111 * @param {boolean=} exclusive
112 */
113
114
115 left(value, exclusive = false) {
116 this._left.push([value, exclusive]);
117 }
118 /**
119 * @param {number} value
120 * @param {boolean=} exclusive
121 */
122
123
124 right(value, exclusive = false) {
125 this._right.push([value, exclusive]);
126 }
127 /**
128 * @param {boolean} logic is not logic applied
129 * @return {string} "smart" range string representation
130 */
131
132
133 format(logic = true) {
134 const [start, leftExclusive] = Range.getRangeValue(this._left, logic);
135 const [end, rightExclusive] = Range.getRangeValue(this._right, !logic);
136
137 if (!Number.isFinite(start) && !Number.isFinite(end)) {
138 return '';
139 }
140
141 const realStart = leftExclusive ? start + 1 : start;
142 const realEnd = rightExclusive ? end - 1 : end; // e.g. 5 < x < 7, 5 < x <= 6, 6 <= x <= 6
143
144 if (realStart === realEnd) {
145 return `should be ${logic ? '' : '!'}= ${realStart}`;
146 } // e.g. 4 < x < ∞
147
148
149 if (Number.isFinite(start) && !Number.isFinite(end)) {
150 return Range.formatLeft(start, logic, leftExclusive);
151 } // e.g. ∞ < x < 4
152
153
154 if (!Number.isFinite(start) && Number.isFinite(end)) {
155 return Range.formatRight(end, logic, rightExclusive);
156 }
157
158 return Range.formatRange(start, end, leftExclusive, rightExclusive, logic);
159 }
160
161}
162
163module.exports = Range;
Note: See TracBrowser for help on using the repository browser.