1
0

refactoring

This commit is contained in:
2025-05-24 13:34:58 +02:00
parent be1a8e3670
commit cd710aab9e
4 changed files with 66 additions and 80 deletions

View File

@@ -1,5 +1,4 @@
export * from "./placeholder.js";
export * from "./pattern.js";
export * as VariableResolvers from "./resolver/index.js";
export * from "./resolver/types.js";
export * as UnknownVariableHandlers from "./unknown-variable-handler/index.js";

View File

@@ -1,17 +0,0 @@
export class PlaceholderPattern {
readonly #prefix: string;
readonly #suffix: string;
public constructor(prefix: string, suffix: string) {
this.#prefix = prefix;
this.#suffix = suffix;
}
public get prefix() {
return this.#prefix;
}
public get suffix() {
return this.#suffix;
}
}

View File

@@ -1,11 +1,14 @@
import { AbortSubstitutionException, PlaceholderException } from "./exceptions.js";
import { PlaceholderPattern } from "./pattern.js";
import { EMPTY as emptyResolver } from "./resolver/index.js";
import { VariableResolver } from "./resolver/types.js";
import { StringSection } from "./string-section.js";
import { UnknownVariableHandler } from "./unknown-variable-handler/types.js";
import { isDefined, Nullable } from "./utils.js";
export type PlaceholderPattern = {
prefix: string;
suffix: string;
};
export type PlaceholderOptions = {
pattern?: PlaceholderPattern;
escapeChar?: string;
@@ -14,13 +17,13 @@ export type PlaceholderOptions = {
unknownVariableHandler?: Nullable<UnknownVariableHandler>;
};
const DEFAULT_OPTIONS: Required<PlaceholderOptions> = {
pattern: new PlaceholderPattern("${", "}"),
const DEFAULT_OPTIONS: Required<PlaceholderOptions> = Object.freeze({
pattern: Object.freeze({ prefix: "${", suffix: "}" }),
escapeChar: '\\',
recursive: false,
resolver: emptyResolver,
unknownVariableHandler: null
};
});
export class PlaceholderSubstitutor {
readonly #pattern: PlaceholderPattern;
@@ -108,7 +111,7 @@ class Substitutor {
}
const innerSubstitutor = new Substitutor(this.#substitutor, this.#input.subSection(this.#pos), true);
const variable = innerSubstitutor.replace();
const variable = innerSubstitutor.replace().trim();
if (variable.length === 0) {
throw new PlaceholderException(this.#input.getSection(), this.#pos, "Empty variable");
@@ -178,7 +181,7 @@ class Substitutor {
return this.#substitutor.unknownVariableHandler(this.#substitutor, name);
} catch (e: any) {
if (e instanceof AbortSubstitutionException) {
throw new PlaceholderException(this.#input.getSection(), this.#pos, "Substitution aborted due to unknown variable", e);
throw new PlaceholderException(this.#input.getSection(), this.#pos, `Substitution aborted due to unknown variable: ${name}`, e);
}
throw new PlaceholderException(this.#input.getSection(), this.#pos, "An error occurred while handling unknown variable", e);
@@ -188,3 +191,59 @@ class Substitutor {
return null;
}
}
class StringSection {
readonly #parent: string;
readonly #offset: number;
readonly #length: number;
constructor(parent: string, offset: number = 0, length: number = parent.length - offset) {
if (offset < 0) {
throw new Error("offset < 0");
}
if (length < 0) {
throw new Error("length < 0");
}
if (offset + length > parent.length) {
throw new Error("offset + length > parent.length");
}
this.#parent = parent;
this.#offset = offset;
this.#length = length;
}
public get length() {
return this.#length;
}
public getSection() {
return this.substring(0);
}
public subSection(offset: number = 0, length: number = this.#length - offset) {
return new StringSection(this.#parent, this.#offset + offset, length);
}
public charAt(index: number) {
return this.#parent.charAt(this.#offset + index);
}
public startsWith(prefix: string, offset: number = 0) {
return prefix.length <= (this.#length - offset) && this.#parent.startsWith(prefix, this.#offset + offset);
}
public substring(beginIndex: number = 0, endIndex: number = this.#length - beginIndex) {
return this.#parent.substring(this.#offset + beginIndex, this.#offset + endIndex);
}
public toJSON() {
return this.getSection();
}
public toString() {
return this.getSection();
}
}

View File

@@ -1,55 +0,0 @@
export class StringSection {
readonly #parent: string;
readonly #offset: number;
readonly #length: number;
constructor(parent: string, offset: number = 0, length: number = parent.length - offset) {
if (offset < 0) {
throw new Error("offset < 0");
}
if (length < 0) {
throw new Error("length < 0");
}
if (offset + length > parent.length) {
throw new Error("offset + length > parent.length");
}
this.#parent = parent;
this.#offset = offset;
this.#length = length;
}
public get length() {
return this.#length;
}
public getSection() {
return this.substring(0);
}
public subSection(offset: number = 0, length: number = this.#length - offset) {
return new StringSection(this.#parent, this.#offset + offset, length);
}
public charAt(index: number) {
return this.#parent.charAt(this.#offset + index);
}
public startsWith(prefix: string, offset: number = 0) {
return prefix.length <= (this.#length - offset) && this.#parent.startsWith(prefix, this.#offset + offset);
}
public substring(beginIndex: number = 0, endIndex: number = this.#length - beginIndex) {
return this.#parent.substring(this.#offset + beginIndex, this.#offset + endIndex);
}
public toJSON() {
return this.getSection();
}
public toString() {
return this.getSection();
}
}