-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Introducing Matcher interface for public use
- Loading branch information
1 parent
d5de736
commit 78fb265
Showing
8 changed files
with
125 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import { Encounter } from './Encounter'; | ||
import { Language } from '../../language/Language'; | ||
import { Node } from '../Node'; | ||
|
||
import { MatchingState, emptyState } from './MatchingState'; | ||
import { MatchSet } from './MatchSet'; | ||
import { MatchOptions } from './MatchOptions'; | ||
import { EncounterOptions } from './EncounterOptions'; | ||
|
||
export interface MatchReductionEncounter<RawData, MappedData> { | ||
encounter: Encounter; | ||
|
||
results: MatchSet<RawData>; | ||
|
||
map: (object: RawData) => MappedData; | ||
} | ||
|
||
export interface MatcherOptions<V> extends EncounterOptions { | ||
name?: string; | ||
|
||
reducer?: (reduction: MatchReductionEncounter<any, any>) => V; | ||
|
||
mapper?: (result: any, encounter: Encounter) => any; | ||
} | ||
|
||
/** | ||
* Matcher that can match expressions against a graph. | ||
*/ | ||
export class DefaultMatcher<V> { | ||
public readonly language: Language; | ||
public readonly nodes: Node[]; | ||
public readonly options: MatcherOptions<V>; | ||
|
||
/** | ||
* Internal state of this matcher that is accessed if it is used as a | ||
* sub graph. | ||
*/ | ||
public matchingState: MatchingState; | ||
|
||
constructor(language: Language, nodes: Node[], options: MatcherOptions<V>) { | ||
this.language = language; | ||
this.nodes = nodes; | ||
|
||
this.options = options; | ||
this.matchingState = emptyState(); | ||
} | ||
|
||
/** | ||
* Match against the given expression. | ||
* | ||
* @param {string} expression | ||
* @param {object} options | ||
* @return {Promise} | ||
*/ | ||
public match(expression: string, options: MatchOptions={}): Promise<V> { | ||
if(typeof expression !== 'string') { | ||
throw new Error('Can only match against string expressions'); | ||
} | ||
|
||
const resolvedOptions = Object.assign({ | ||
onlyComplete: true | ||
}, this.options, options); | ||
|
||
const tokens = this.language.tokenize(expression); | ||
const encounter = new Encounter(tokens, resolvedOptions); | ||
encounter.outgoing = this.nodes; | ||
|
||
const promise = encounter.next(0, 0) | ||
.then(() => { | ||
return encounter.matches; | ||
}); | ||
|
||
if(this.options.reducer) { | ||
const reducer = this.options.reducer; | ||
return promise.then((results: MatchSet<any>) => reducer({ | ||
results, | ||
encounter, | ||
map: (object: any) => this.options.mapper | ||
? this.options.mapper(object, encounter) | ||
: object | ||
} | ||
)); | ||
} else { | ||
return promise.then((results: MatchSet<any>) => { | ||
const asArray = results.toArray(); | ||
let mapped; | ||
if(this.options.mapper) { | ||
const mapper = this.options.mapper; | ||
mapped = asArray.map(match => mapper(match.data, encounter)); | ||
} else { | ||
mapped = asArray.map(match => match.data); | ||
} | ||
|
||
// Forcefully convert into V type | ||
return mapped as unknown as V; | ||
}); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,99 +1,15 @@ | ||
import { Encounter } from './Encounter'; | ||
import { Language } from '../../language/Language'; | ||
import { Node } from '../Node'; | ||
|
||
import { MatchingState, emptyState } from './MatchingState'; | ||
import { MatchSet } from './MatchSet'; | ||
import { MatchOptions } from './MatchOptions'; | ||
import { EncounterOptions } from './EncounterOptions'; | ||
|
||
export interface MatchReductionEncounter<RawData, MappedData> { | ||
encounter: Encounter; | ||
|
||
results: MatchSet<RawData>; | ||
|
||
map: (object: RawData) => MappedData; | ||
} | ||
|
||
export interface MatcherOptions<V> extends EncounterOptions { | ||
name?: string; | ||
|
||
reducer?: (reduction: MatchReductionEncounter<any, any>) => V; | ||
|
||
mapper?: (result: any, encounter: Encounter) => any; | ||
} | ||
|
||
/** | ||
* Matcher that can match expressions against a graph. | ||
*/ | ||
export class Matcher<V> { | ||
public readonly language: Language; | ||
public readonly nodes: Node[]; | ||
public readonly options: MatcherOptions<V>; | ||
|
||
/** | ||
* Internal state of this matcher that is accessed if it is used as a | ||
* sub graph. | ||
*/ | ||
public matchingState: MatchingState; | ||
|
||
constructor(language: Language, nodes: Node[], options: MatcherOptions<V>) { | ||
this.language = language; | ||
this.nodes = nodes; | ||
|
||
this.options = options; | ||
this.matchingState = emptyState(); | ||
} | ||
|
||
export interface Matcher<V> { | ||
/** | ||
* Match against the given expression. | ||
* | ||
* @param {string} expression | ||
* @param {object} options | ||
* @return {Promise} | ||
* @param expression | ||
* @param options | ||
* @return | ||
*/ | ||
public match(expression: string, options: MatchOptions={}): Promise<V> { | ||
if(typeof expression !== 'string') { | ||
throw new Error('Can only match against string expressions'); | ||
} | ||
|
||
const resolvedOptions = Object.assign({ | ||
onlyComplete: true | ||
}, this.options, options); | ||
|
||
const tokens = this.language.tokenize(expression); | ||
const encounter = new Encounter(tokens, resolvedOptions); | ||
encounter.outgoing = this.nodes; | ||
|
||
const promise = encounter.next(0, 0) | ||
.then(() => { | ||
return encounter.matches; | ||
}); | ||
|
||
if(this.options.reducer) { | ||
const reducer = this.options.reducer; | ||
return promise.then((results: MatchSet<any>) => reducer({ | ||
results, | ||
encounter, | ||
map: (object: any) => this.options.mapper | ||
? this.options.mapper(object, encounter) | ||
: object | ||
} | ||
)); | ||
} else { | ||
return promise.then((results: MatchSet<any>) => { | ||
const asArray = results.toArray(); | ||
let mapped; | ||
if(this.options.mapper) { | ||
const mapper = this.options.mapper; | ||
mapped = asArray.map(match => mapper(match.data, encounter)); | ||
} else { | ||
mapped = asArray.map(match => match.data); | ||
} | ||
|
||
// Forcefully convert into V type | ||
return mapped as unknown as V; | ||
}); | ||
} | ||
} | ||
match(expression: string, options?: MatchOptions): Promise<V>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters