From e49e610b21a1e4dfb743a04635fa0134f9911a43 Mon Sep 17 00:00:00 2001 From: Stephan Besser Date: Wed, 4 Dec 2024 09:13:31 +0100 Subject: [PATCH] refactor: simplify IFormatParser interface and enhance options schema for format parsers --- src/formats/base-format.ts | 9 --------- src/parser.ts | 40 ++++++++++++++++++++++++++------------ 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/formats/base-format.ts b/src/formats/base-format.ts index a8b4bcc..72feeeb 100644 --- a/src/formats/base-format.ts +++ b/src/formats/base-format.ts @@ -13,16 +13,7 @@ export const OptionsSchema = z export type Config = z.infer; export interface IFormatParser { - precision: number; - longitude: number | undefined; - latitude: number | undefined; - parse(coordinateString: string): Coordinate; - enforceValidLongitude(lonValue: unknown): void; - enforceValidLatitude(latValue: unknown): void; - enforceNoHyphen(coordinateString: string): void; - dmsToDecimal(dms: DmsCoordinate): number; - reset(): void; } export class BaseFormat implements IFormatParser { diff --git a/src/parser.ts b/src/parser.ts index 9f4bb4b..5c14bfd 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -11,11 +11,19 @@ import { validateSchema } from './validate-schema.js'; export const OptionsSchema = z .object({ precision: z.number().int().min(0).max(15), + extendFormatParsers: z.boolean().optional(), + formatParsers: z.array(z.any()).optional(), }) .strict() .optional() .describe('OptionsSchema'); -export type Options = z.infer; + +export type Options = { + precision: number; + // if true, the given format parsers will be appended to the default parsers instead of replacing them + extendFormatParsers?: boolean; + formatParsers?: IFormatParser[]; +}; export class Parser { originalString: string; @@ -28,20 +36,28 @@ export class Parser { validateSchema(coordinateString, z.string(), { assert: true, name: 'coordinateString' }); validateSchema(options, OptionsSchema, { assert: true, name: 'options' }); - const defaultOptions = { precision: 3 }; - const opts = { ...defaultOptions, ...options }; - + const defaultOptions = { + precision: 3, + extendFormatParsers: false, + }; + const { precision, extendFormatParsers } = { ...defaultOptions, ...options }; + // set default format parsers to use if not provided + const defaultParsers = [ + new DecimalFormat({ precision: precision }), + new DecimalHemiFormat({ precision: precision }), + new DecimalSexaFormat({ precision: precision }), + new DecimalSexaHemiFormat({ precision: precision }), + new DmsDecimalMinFormat({ precision: precision }), + ]; + let formatParsers = options?.formatParsers || defaultParsers; + if (formatParsers.length > 0 && extendFormatParsers === true) { + formatParsers = [...defaultParsers, ...formatParsers]; + } this.originalString = coordinateString; - this.opts = opts; + this.opts = { precision: precision }; this.latitude = undefined; this.longitude = undefined; - this.parsers = [ - new DecimalFormat(this.opts), - new DecimalHemiFormat(this.opts), - new DecimalSexaFormat(this.opts), - new DecimalSexaHemiFormat(this.opts), - new DmsDecimalMinFormat(this.opts), - ]; + this.parsers = formatParsers; try { const { longitude, latitude } = this.parse(coordinateString);