forked from MapComplete/MapComplete
		
	
		
			
	
	
		
			85 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			85 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| 
								 | 
							
								import {Tag} from "./Tag";
							 | 
						||
| 
								 | 
							
								import {TagsFilter} from "./TagsFilter";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export class RegexTag extends TagsFilter {
							 | 
						||
| 
								 | 
							
								    private readonly key: RegExp | string;
							 | 
						||
| 
								 | 
							
								    private readonly value: RegExp | string;
							 | 
						||
| 
								 | 
							
								    private readonly invert: boolean;
							 | 
						||
| 
								 | 
							
								    private readonly matchesEmpty: boolean
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    constructor(key: string | RegExp, value: RegExp | string, invert: boolean = false) {
							 | 
						||
| 
								 | 
							
								        super();
							 | 
						||
| 
								 | 
							
								        this.key = key;
							 | 
						||
| 
								 | 
							
								        this.value = value;
							 | 
						||
| 
								 | 
							
								        this.invert = invert;
							 | 
						||
| 
								 | 
							
								        this.matchesEmpty = RegexTag.doesMatch("", this.value);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    private static doesMatch(fromTag: string, possibleRegex: string | RegExp): boolean {
							 | 
						||
| 
								 | 
							
								        if (typeof possibleRegex === "string") {
							 | 
						||
| 
								 | 
							
								            return fromTag === possibleRegex;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return fromTag.match(possibleRegex) !== null;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    private static source(r: string | RegExp) {
							 | 
						||
| 
								 | 
							
								        if (typeof (r) === "string") {
							 | 
						||
| 
								 | 
							
								            return r;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return r.source;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    asOverpass(): string[] {
							 | 
						||
| 
								 | 
							
								        if (typeof this.key === "string") {
							 | 
						||
| 
								 | 
							
								            return [`['${this.key}'${this.invert ? "!" : ""}~'${RegexTag.source(this.value)}']`];
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return [`[~'${this.key.source}'${this.invert ? "!" : ""}~'${RegexTag.source(this.value)}']`];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    isUsableAsAnswer(): boolean {
							 | 
						||
| 
								 | 
							
								        return false;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    matchesProperties(tags: any): boolean {
							 | 
						||
| 
								 | 
							
								        for (const key in tags) {
							 | 
						||
| 
								 | 
							
								            if (RegexTag.doesMatch(key, this.key)) {
							 | 
						||
| 
								 | 
							
								                const value = tags[key]
							 | 
						||
| 
								 | 
							
								                return RegexTag.doesMatch(value, this.value) != this.invert;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (this.matchesEmpty) {
							 | 
						||
| 
								 | 
							
								            // The value is 'empty'
							 | 
						||
| 
								 | 
							
								            return !this.invert;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        // The matching key was not found
							 | 
						||
| 
								 | 
							
								        return this.invert;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    substituteValues(tags: any): TagsFilter {
							 | 
						||
| 
								 | 
							
								        return this;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    asHumanString() {
							 | 
						||
| 
								 | 
							
								        if (typeof this.key === "string") {
							 | 
						||
| 
								 | 
							
								            return `${this.key}${this.invert ? "!" : ""}~${RegexTag.source(this.value)}`;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return `${this.key.source}${this.invert ? "!" : ""}~~${RegexTag.source(this.value)}`
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    isEquivalent(other: TagsFilter): boolean {
							 | 
						||
| 
								 | 
							
								        if (other instanceof RegexTag) {
							 | 
						||
| 
								 | 
							
								            return other.asHumanString() == this.asHumanString();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (other instanceof Tag) {
							 | 
						||
| 
								 | 
							
								            return RegexTag.doesMatch(other.key, this.key) && RegexTag.doesMatch(other.value, this.value);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return false;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    usedKeys(): string[] {
							 | 
						||
| 
								 | 
							
								        if (typeof this.key === "string") {
							 | 
						||
| 
								 | 
							
								            return [this.key];
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        throw "Key cannot be determined as it is a regex"
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |