luck => isSome(luck) ? luck.some !== undefined ? luckAsMaybe(read(luck.some)) : luckFrom( noneFrom('No value specified.') // AB: TODO: some name, but no value (needs a special treatment in optional/required) ) : luckFrom( noneFrom('No argument specified.') // no name )
function readVerbosity(value: string): bt.Tried<Severity, string> { const normalized = value.toLowerCase(); switch (normalized) { case 'debug': return bt.luckFrom(Severity.Debug); case 'info': return bt.luckFrom(Severity.Info); case 'warning': return bt.luckFrom(Severity.Warning); case 'error': return bt.luckFrom(Severity.Error); default: return bt.fuckFrom('Unexpected value \'' + value + '\' for a verbosity.'); } }
export function readFlag(value: string): Tried<boolean, string> { switch (value) { case 'true': case '1': case 'y': return luckFrom(true); case 'false': case '0': case 'n': return luckFrom(false); default: return fuckFrom('Unexpected value \'' + value + '\' of a flag argument.'); } }
export function toRunner<Options, State, Shared>( ruleKey: string, configs: Configs, toOptions: (config: {}) => bt.Tried<Options, string[]>, rule: FileRule<Options, State, Shared> ): bt.Tried<bo.Optional<Runner<Shared>>, string[]> { const config = configs[ruleKey]; if (config !== undefined) { return bt.insteadFuck( bt.insteadLuck( toOptions(config), options => { const runner = runnerFrom( ruleKey, (program, shared) => applyFileRule(program, options, rule, ruleKey, shared) ); return bo.someFrom(runner) } ), problems => ba.insteadEach( problems, problem => 'Rule \'' + ruleKey + '\' has invalid configuration. ' + problem ) ); } else { return bt.luckFrom( bo.noneFrom('Rule \'' + ruleKey + '\' is disabled due to not being configured.') ); } }
function reading<Before, Value>( before: Tried<Before, string[]>, all: LooselyParsedResult, fullName: string, shortName: string | undefined, read: (value: string) => Tried<Value, string> ): Finishing<Before, Value> { const parsed = shortName !== undefined ? oneOrAnotherOrNeitherButNotBoth( tryAt(all.fullArgs, fullName), tryAt(all.shortArgs, shortName) ) : luckFrom(tryAt(all.fullArgs, fullName)); // attempt to read a string value as boolean const recognized = offTried( parsed, luck => isSome(luck) ? luck.some !== undefined ? luckAsMaybe(read(luck.some)) : luckFrom( noneFrom('No value specified.') // AB: TODO: some name, but no value (needs a special treatment in optional/required) ) : luckFrom( noneFrom('No argument specified.') // no name ) , f**k => fuckFrom(f**k) ); return new Finishing(all, before, recognized); }
(built, recognized) => isSome(recognized) ? luckFrom( take( built, recognized.some ) ) : fuckFrom([recognized.none]),
export function toRunners<Shared extends PerNodeShared & PerFileShared>( configs: Configs ): bt.Tried<bo.Optional<Runner<Shared>>[], string[]> { const all = [ toRunner('bad-comment', configs, config => readFileFilterOptions(config), building().stateless(toBadComment).perNode().file().perFile(x => x).rule), toRunner('no-throw', configs, toEmptyOptions, building().stateless(toNoThrow).perNode().file().perFile(x => x).rule), toRunner( 'no-export-import', configs, config => readFileFilterOptions(config), building().stateless(noExportImport).perNode().file().perFile(x => x).rule ), toRunner('no-primitive-to-self', configs, config => readFileFilterOptions(config), building().stateless(toNoPrimitiveToSelf).perNode().file().perFile(x => x).rule), toRunner('no-expressionless-return', configs, toEmptyOptions, building().stateless(toNoExpressionlessReturn).perNode().file().perFile(x => x).rule), toRunner('no-unnecessary-annotations', configs, toEmptyOptions, building().stateless(toNoUnnecessaryAnnotations).perNode().file().perFile(x => x).rule), toRunner('no-unnecessary-assertions', configs, toEmptyOptions, building().stateless(toNoUnnecessaryAssertions).perNode().file().perFile(x => x).rule), toRunner('names-stat', configs, config => { const ruleOptions = nameStat.toOptions(config); const fileOptions = readFileFilterOptions(config); const options = bothLucks(ruleOptions, fileOptions, fuse, concat); return options; }, building().stateful(nameStat.toRule()).perNode().file().perFile(x => x).rule), toRunner( 'no-const-lambdas', configs, config => readFileFilterOptions(config), building().stateless(noConstLambdas).perNode().file().perFile(x => x).rule ), toRunner('banned-names', configs, toEmptyOptions, building().stateful(toBannedNames).perNode().file().perFile(x => x).rule), toRunner('no-symbol', configs, toEmptyOptions, building().stateless(toNoUndeclaredSymbols).perNode().file().perFile(x => x).rule), toRunner('const-needed', configs, config => readFileFilterOptions(config), building().stateful(toConstNeeded).perNode().file().perFile(x => x).rule) ]; const [goods, bads] = partition(all); return bads.length > 0 ? bt.fuckFrom( ba.concatAll(bads) ) : bt.luckFrom(goods); }
export function read<Parsing, Parsed>( value: string, parsing: Parsing, builder: Builder<Parsing>, asParsed: (parsing: Parsing) => Optional<Parsed> ): Tried<Parsed, Error> { const stand = standFrom(mightNeedCommandOrParameter, []); const started = keepReading(parsing, value, 0, stand, builder); if (isLuck(started)) { const finished = finishReading(started.luck.result, started.luck.stand, builder) if (isLuck(finished)) { const parsed = asParsed(finished.luck); if (isSome(parsed)) { return luckFrom(parsed.some); } else { return toFailedToFindBuilderInParameterState(); } } else { return finished; } } else { return started; } }
export function toEmptyOptions(): bt.Luck<{}> { return bt.luckFrom({}); }
function luck<State>(parsing: LooselyParsing, state: State): Luck<Expected<State, LooselyParsing>> { return luckFrom(expectedFrom(parsing, state)); }