UNPKG

create-expo-cljs-app

Version:

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

298 lines (259 loc) 8.07 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, requireNonNull} from '../assert'; import {DateTimeBuilder} from './DateTimeBuilder'; import {EnumMap} from './EnumMap'; import {IsoChronology} from '../chrono/IsoChronology'; import {Temporal} from '../temporal/Temporal'; import {TemporalQueries} from '../temporal/TemporalQueries'; /** * @private */ export class DateTimeParseContext{ constructor(){ if(arguments.length === 1){ if(arguments[0] instanceof DateTimeParseContext){ this._constructorSelf.apply(this, arguments); return; } else { this._constructorFormatter.apply(this, arguments); } } else { this._constructorParam.apply(this, arguments); } this._caseSensitive = true; this._strict = true; this._parsed = [new Parsed(this)]; } _constructorParam(locale, symbols, chronology){ this._locale = locale; this._symbols = symbols; this._overrideChronology = chronology; } _constructorFormatter(formatter){ this._locale = formatter.locale(); this._symbols = formatter.decimalStyle(); this._overrideChronology = formatter.chronology(); } _constructorSelf(other) { this._locale = other._locale; this._symbols = other._symbols; this._overrideChronology = other._overrideChronology; this._overrideZone = other._overrideZone; this._caseSensitive = other._caseSensitive; this._strict = other._strict; this._parsed = [new Parsed(this)]; } /** * Creates a copy of this context. */ copy() { return new DateTimeParseContext(this); } symbols(){ return this._symbols; } isStrict(){ return this._strict; } setStrict(strict){ this._strict = strict; } locale() { return this._locale; } setLocale(locale) { this._locale = locale; } //----------------------------------------------------------------------- /** * Starts the parsing of an optional segment of the input. */ startOptional() { this._parsed.push(this.currentParsed().copy()); } /** * Ends the parsing of an optional segment of the input. * * @param {boolean} successful whether the optional segment was successfully parsed */ endOptional(successful) { if (successful) { this._parsed.splice(this._parsed.length - 2, 1); } else { this._parsed.splice(this._parsed.length - 1, 1); } } /** * Checks if parsing is case sensitive. * * @return true if parsing is case sensitive, false if case insensitive */ isCaseSensitive() { return this._caseSensitive; } /** * Sets whether the parsing is case sensitive or not. * * @param caseSensitive changes the parsing to be case sensitive or not from now on */ setCaseSensitive(caseSensitive) { this._caseSensitive = caseSensitive; } /** * Helper to compare two {@link CharSequence} instances. * This uses {@link isCaseSensitive}. * * @param cs1 the first character sequence, not null * @param offset1 the offset into the first sequence, valid * @param cs2 the second character sequence, not null * @param offset2 the offset into the second sequence, valid * @param length the length to check, valid * @return true if equal */ subSequenceEquals(cs1, offset1, cs2, offset2, length) { if (offset1 + length > cs1.length || offset2 + length > cs2.length) { return false; } if (! this.isCaseSensitive()) { cs1 = cs1.toLowerCase(); cs2 = cs2.toLowerCase(); } for (let i = 0; i < length; i++) { const ch1 = cs1[offset1 + i]; const ch2 = cs2[offset2 + i]; if (ch1 !== ch2) { return false; } } return true; } /** * Helper to compare two `char`. * This uses {@link isCaseSensitive}. * * @param ch1 the first character * @param ch2 the second character * @return true if equal */ charEquals(ch1, ch2) { if (this.isCaseSensitive()) { return ch1 === ch2; } return this.charEqualsIgnoreCase(ch1, ch2); } /** * Compares two characters ignoring case. * * @param c1 the first * @param c2 the second * @return true if equal */ charEqualsIgnoreCase(c1, c2) { return c1 === c2 || c1.toLowerCase() === c2.toLowerCase(); } setParsedField(field, value, errorPos, successPos){ const currentParsedFieldValues = this.currentParsed().fieldValues; const old = currentParsedFieldValues.get(field); currentParsedFieldValues.set(field, value); return (old != null && old !== value) ? ~errorPos : successPos; } /** * Stores the parsed zone. * * This stores the zone that has been parsed. * No validation is performed other than ensuring it is not null. * * @param {ZoneId} zone the parsed zone, not null */ setParsedZone(zone) { requireNonNull(zone, 'zone'); this.currentParsed().zone = zone; } getParsed(field) { return this.currentParsed().fieldValues.get(field); } toParsed() { return this.currentParsed(); } currentParsed() { return this._parsed[this._parsed.length - 1]; } /** * Stores the leap second. */ setParsedLeapSecond() { this.currentParsed().leapSecond = true; } /** * Gets the effective chronology during parsing. * * @return the effective parsing chronology, not null */ getEffectiveChronology() { let chrono = this.currentParsed().chrono; if (chrono == null) { chrono = this._overrideChronology; if (chrono == null) { chrono = IsoChronology.INSTANCE; } } return chrono; } } class Parsed extends Temporal { constructor(dateTimeParseContext){ super(); this.chrono = null; this.zone = null; this.fieldValues = new EnumMap(); this.leapSecond = false; this.dateTimeParseContext = dateTimeParseContext; } copy() { const cloned = new Parsed(); cloned.chrono = this.chrono; cloned.zone = this.zone; cloned.fieldValues.putAll(this.fieldValues); cloned.leapSecond = this.leapSecond; cloned.dateTimeParseContext = this.dateTimeParseContext; return cloned; } toString() { return `${this.fieldValues}, ${this.chrono}, ${this.zone}`; } isSupported(field) { return this.fieldValues.containsKey(field); } get(field) { const val = this.fieldValues.get(field); assert(val != null); return val; } query(query) { if (query === TemporalQueries.chronology()) { return this.chrono; } if (query === TemporalQueries.zoneId() || query === TemporalQueries.zone()) { return this.zone; } return super.query(query); } toBuilder() { const builder = new DateTimeBuilder(); builder.fieldValues.putAll(this.fieldValues); builder.chrono = this.dateTimeParseContext.getEffectiveChronology(); if (this.zone != null) { builder.zone = this.zone; } else { builder.zone = this.overrideZone; } builder.leapSecond = this.leapSecond; builder.excessDays = this.excessDays; return builder; } }