69 lines
1.8 KiB
JavaScript
69 lines
1.8 KiB
JavaScript
|
class PropertyList {
|
||
|
constructor(...properties) {
|
||
|
for (const property of properties) {
|
||
|
if (!(property instanceof Property))
|
||
|
throw TypeError("properties has to be instances of Property");
|
||
|
}
|
||
|
|
||
|
this.properties = [];
|
||
|
|
||
|
for (const property of properties) {
|
||
|
this.add(property);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
add(property) {
|
||
|
Object.defineProperty(this, property.key, {
|
||
|
get() { return property.value },
|
||
|
set(value) { property.parse(value) }
|
||
|
});
|
||
|
|
||
|
this.properties.push(property);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export class Property {
|
||
|
constructor(key, defaultValue = null, parser = (v) => v) {
|
||
|
this.key = key;
|
||
|
this.defaultValue = defaultValue;
|
||
|
this.parser = parser;
|
||
|
|
||
|
this.parse(this.defaultValue);
|
||
|
}
|
||
|
|
||
|
parse(v) {
|
||
|
this.value = this.parser(v);
|
||
|
return this.value;
|
||
|
}
|
||
|
|
||
|
clone() {
|
||
|
return new Property(this.key, this.defaultValue, this.parser);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** Regex attempts (first to final)
|
||
|
* ^\s*({0})\s*(=|:)\s*(.*)$
|
||
|
* ^\s*({0})\s*(=|:)\s*([^#\n]*).*$
|
||
|
* ^\s*({0})\s*(=|:)\s*(.*?)((#|\/\/).*)?$
|
||
|
*/
|
||
|
|
||
|
export class PropertyReader {
|
||
|
constructor(...properties) {
|
||
|
this.propertyList = new PropertyList(...properties);
|
||
|
this.regex = new RegExp(`^\\s*(${this.propertyList.properties.map(p => p.key).join("|")})\\s*(=|:)\\s*(.*?)((#|\\/\\/).*)?$`, "mg");
|
||
|
}
|
||
|
|
||
|
read(str) {
|
||
|
let match = null;
|
||
|
while ((match = this.regex.exec(str)) !== null) {
|
||
|
if (match.index === this.regex.lastIndex) // Infinite loop fix
|
||
|
this.regex.lastIndex++;
|
||
|
|
||
|
const key = match[1];
|
||
|
const value = match[3].trim();
|
||
|
this.propertyList[key] = value;
|
||
|
}
|
||
|
|
||
|
return this.propertyList;
|
||
|
}
|
||
|
}
|