export interface LogLevel { /** * The log level string representation */ readonly levelName: string; /** * The log level numeric value */ readonly level: number; } /** * Construct Type from arguments * * @param levelName - the level string representation * @param level - the level value * @returns a new LoggerType */ export function LogLevel(levelName: string, level: number): LogLevel { return { levelName, level }; } export namespace LogLevel { /** * * @param left - the left element * @param right - the right element * * @returns the comparison result */ export function compare(left: LogLevel, right: LogLevel): 1 | 0 | -1 { const diff = LogLevel.value(left) - LogLevel.value(right); return diff === 0 ? diff : diff < 0 ? -1 : 1; } /** * * @param level - the log level * @returns the level string representation */ export function stringify(level: LogLevel): string { return level.levelName; } /** * * @param level - the log level * @returns the level numerical value */ export function value(level: LogLevel): number { return level.level; } /** * Build a matching function `(anyLevelValue) => value` from a list of tuples `[level1, value1], [level2, value2], ...` * * @param matchers */ export function match(matchers: [LogLevel, T][]): (anyLevelValue: LogLevel['level']) => null | undefined | T; export function match(matchers: [LogLevel, T][], defaultValue: T): (anyLevelValue: LogLevel['level']) => T; export function match( matchers: [LogLevel, T][], defaultValue?: T ): (anyLevelValue: LogLevel['level']) => null | undefined | T { const orderedMatchers = [...matchers]; const level = 0; const returnValue = 1; const levelNone = { level: Number.NEGATIVE_INFINITY, levelName: 'None' }; const first: [LogLevel, null | undefined | T] = [levelNone, defaultValue]; return orderedMatchers.length === 0 ? () => defaultValue : (anyLevelValue) => orderedMatchers.reduce( (acc, matcher) => LogLevel.compare(matcher[level], acc[level]) > 0 && anyLevelValue >= matcher[level].level ? matcher : acc, first )[returnValue]; } export const Critical = LogLevel('Critical', 50); export const Error = LogLevel('Error', 40); export const Warning = LogLevel('Warning', 30); export const Info = LogLevel('Info', 20); export const Debug = LogLevel('Debug', 10); }