{"version":3,"file":"enum.mjs","sources":["../../src/enum/enum.mts"],"sourcesContent":["import { ISet, isString, memoizeFunction, Result } from 'ts-data-forge';\nimport {\n  type ArrayElement,\n  type NonEmptyTuple,\n  type Primitive,\n} from 'ts-type-forge';\nimport { string } from '../primitives/index.mjs';\nimport { type Type } from '../type.mjs';\nimport {\n  createAssertFn,\n  createCastFn,\n  createIsFn,\n  type ValidationError,\n} from '../utils/index.mjs';\n\nexport function enumType<const Values extends NonEmptyTuple<Primitive>>(\n  values: Values,\n  options?: Partial<\n    Readonly<{\n      typeName: string;\n      defaultValue: ArrayElement<Values>;\n      allowAnyString: false;\n    }>\n  >,\n): Type<ArrayElement<Values>>;\n\n// When `allowAnyString` is on, the result type keeps autocomplete for the\n// listed members via the `T | (string & {})` idiom while still accepting any\n// other string, and at runtime the value is validated as a plain string\n// (i.e. it behaves like `string()`).\nexport function enumType<const Values extends NonEmptyTuple<string>>(\n  values: Values,\n  options: Readonly<{\n    allowAnyString: true;\n    typeName?: string;\n    defaultValue?: ArrayElement<Values> | (string & {});\n  }>,\n): Type<ArrayElement<Values> | (string & {})>;\n\nexport function enumType<const Values extends NonEmptyTuple<Primitive>>(\n  values: Values,\n  options?: Partial<\n    Readonly<{\n      typeName: string;\n      defaultValue: ArrayElement<Values> | (string & {});\n      allowAnyString: boolean;\n    }>\n  >,\n): Type<ArrayElement<Values> | (string & {})> {\n  if (\n    options?.allowAnyString === true &&\n    values.every(isString) &&\n    isString(options.defaultValue)\n  ) {\n    return string(options.defaultValue);\n  }\n\n  type T = ArrayElement<Values> | (string & {});\n\n  const valueSet = ISet.create(values);\n\n  const typeName = options?.typeName ?? 'enum';\n\n  const getDefaultValue = memoizeFunction(\n    // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n    (): T => options?.defaultValue ?? (values[0] as ArrayElement<Values>),\n  );\n\n  const validate: Type<T>['validate'] = (a) =>\n    // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n    valueSet.has(a as Primitive)\n      ? // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n        Result.ok(a as T)\n      : Result.err([\n          {\n            path: [],\n            actualValue: a,\n            expectedType: typeName,\n            typeName,\n            details: {\n              kind: 'enum',\n              values,\n            },\n          } satisfies ValidationError,\n        ]);\n\n  const is = createIsFn<T>(validate);\n\n  const fill: Type<T>['fill'] = (a) => (is(a) ? a : getDefaultValue());\n\n  return {\n    typeName,\n    get defaultValue() {\n      return getDefaultValue();\n    },\n    fill,\n    prune: (a) => a,\n    validate,\n    is,\n    assertIs: createAssertFn(validate),\n    cast: createCastFn(validate),\n  };\n}\n"],"names":[],"mappings":";;;;;;;;AAuCO,SAAS,QAAA,CACd,QACA,OAAA,EAO4C;AAC5C,EAAA,IACE,OAAA,EAAS,cAAA,KAAmB,IAAA,IAC5B,MAAA,CAAO,KAAA,CAAM,QAAQ,CAAA,IACrB,QAAA,CAAS,OAAA,CAAQ,YAAY,CAAA,EAC7B;AACA,IAAA,OAAO,MAAA,CAAO,QAAQ,YAAY,CAAA;AAAA,EACpC;AAIA,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA;AAEnC,EAAA,MAAM,QAAA,GAAW,SAAS,QAAA,IAAY,MAAA;AAEtC,EAAA,MAAM,eAAA,GAAkB,eAAA;AAAA;AAAA,IAEtB,MAAS,OAAA,EAAS,YAAA,IAAiB,MAAA,CAAO,CAAC;AAAA,GAC7C;AAEA,EAAA,MAAM,WAAgC,CAAC,CAAA;AAAA;AAAA,IAErC,QAAA,CAAS,IAAI,CAAc,CAAA;AAAA;AAAA,MAEvB,MAAA,CAAO,GAAG,CAAM;AAAA,QAChB,OAAO,GAAA,CAAI;AAAA,MACT;AAAA,QACE,MAAM,EAAC;AAAA,QACP,WAAA,EAAa,CAAA;AAAA,QACb,YAAA,EAAc,QAAA;AAAA,QACd,QAAA;AAAA,QACA,OAAA,EAAS;AAAA,UACP,IAAA,EAAM,MAAA;AAAA,UACN;AAAA;AACF;AACF,KACD;AAAA,GAAA;AAEP,EAAA,MAAM,EAAA,GAAK,WAAc,QAAQ,CAAA;AAEjC,EAAA,MAAM,OAAwB,CAAC,CAAA,KAAO,GAAG,CAAC,CAAA,GAAI,IAAI,eAAA,EAAgB;AAElE,EAAA,OAAO;AAAA,IACL,QAAA;AAAA,IACA,IAAI,YAAA,GAAe;AACjB,MAAA,OAAO,eAAA,EAAgB;AAAA,IACzB,CAAA;AAAA,IACA,IAAA;AAAA,IACA,KAAA,EAAO,CAAC,CAAA,KAAM,CAAA;AAAA,IACd,QAAA;AAAA,IACA,EAAA;AAAA,IACA,QAAA,EAAU,eAAe,QAAQ,CAAA;AAAA,IACjC,IAAA,EAAM,aAAa,QAAQ;AAAA,GAC7B;AACF;;;;"}