import type { CombinatorInput } from "../combinated";
import { Combinated } from "../combinated";
import type { ParjsCombinator, ParjsProjection } from "../parjser";
import type { ParsingState } from "../state";
import type { ImplicitParjser } from "../wrap-implicit";
import { wrapImplicit } from "../wrap-implicit";
class ThenPick extends Combinated {
type = "then-pick";
expecting = `${this.source.expecting} then `;
constructor(
source: CombinatorInput,
private _ctor: ParjsProjection>
) {
super(source);
}
_apply(ps: ParsingState): void {
this.source.apply(ps);
if (!ps.isOk) {
return;
}
const nextParser = wrapImplicit(this._ctor(ps.value as A, ps.userState));
nextParser.apply(ps);
if (ps.isOk) {
return;
}
if (ps.isSoft) {
ps.kind = "Hard";
}
}
}
/**
* Applies the source parser, and then applies a selector on the source parser's result and user
* state to choose or create the parser to apply next.
*
* @param selector
*/
export function thenPick(
selector: ParjsProjection>
): ParjsCombinator {
return source => new ThenPick(wrapImplicit(source), selector);
}