{"version":3,"file":"set.mjs","sources":["../../src/other-types/set.mts"],"sourcesContent":["import { isSet } from '@sindresorhus/is';\nimport { Arr, memoizeFunction, Result } from 'ts-data-forge';\nimport { type AnyType, type Type, type TypeOf } from '../type.mjs';\nimport {\n  createAssertFn,\n  createCastFn,\n  createIsFn,\n  createPrimitiveValidationError,\n  type ValidationError,\n} from '../utils/index.mjs';\n\ntype SetResultType<T extends AnyType> = ReadonlySet<TypeOf<T>>;\n\nexport const SetType = <T extends AnyType>(\n  elementType: T,\n  options?: Partial<\n    Readonly<{\n      typeName: string;\n    }>\n  >,\n): Type<SetResultType<T>> => {\n  type S = SetResultType<T>;\n\n  const typeName = options?.typeName ?? 'Set';\n\n  const getDefaultValue = memoizeFunction((): S => new Set());\n\n  const validate: Type<S>['validate'] = (a) => {\n    if (!isSet(a)) {\n      return Result.err([\n        createPrimitiveValidationError({\n          actualValue: a,\n          expectedType: 'Set',\n          typeName,\n          details: undefined,\n        }),\n      ]);\n    }\n\n    const errors: readonly ValidationError[] = Arr.generate(function* () {\n      for (const element of a) {\n        const res = elementType.validate(element);\n\n        if (Result.isErr(res)) {\n          yield {\n            path: [],\n            actualValue: element,\n            expectedType: typeName,\n            typeName,\n            details: {\n              kind: 'set-element',\n              expectedType: elementType.typeName,\n            },\n          } satisfies ValidationError;\n\n          yield* res.value;\n        }\n      }\n    });\n\n    if (Arr.isNonEmpty(errors)) {\n      return Result.err(errors);\n    }\n\n    return Result.ok(a);\n  };\n\n  const fill: Type<S>['fill'] = (a) =>\n    !isSet(a)\n      ? getDefaultValue()\n      : new Set(Array.from(a).filter((v) => elementType.is(v)));\n\n  const prune = (a: S): S =>\n    // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n    new Set(Array.from(a, (e) => elementType.prune(e)));\n\n  return {\n    typeName,\n    get defaultValue() {\n      return getDefaultValue();\n    },\n    fill,\n    prune,\n    validate,\n    is: createIsFn(validate),\n    assertIs: createAssertFn(validate),\n    cast: createCastFn(validate),\n  };\n};\n"],"names":[],"mappings":";;;;;;;AAaO,MAAM,OAAA,GAAU,CACrB,WAAA,EACA,OAAA,KAK2B;AAG3B,EAAA,MAAM,QAAA,GAAW,SAAS,QAAA,IAAY,KAAA;AAEtC,EAAA,MAAM,eAAA,GAAkB,eAAA,CAAgB,sBAAS,IAAI,KAAK,CAAA;AAE1D,EAAA,MAAM,QAAA,GAAgC,CAAC,CAAA,KAAM;AAC3C,IAAA,IAAI,CAAC,KAAA,CAAM,CAAC,CAAA,EAAG;AACb,MAAA,OAAO,OAAO,GAAA,CAAI;AAAA,QAChB,8BAAA,CAA+B;AAAA,UAC7B,WAAA,EAAa,CAAA;AAAA,UACb,YAAA,EAAc,KAAA;AAAA,UACd,QAAA;AAAA,UACA,OAAA,EAAS;AAAA,SACV;AAAA,OACF,CAAA;AAAA,IACH;AAEA,IAAA,MAAM,MAAA,GAAqC,GAAA,CAAI,QAAA,CAAS,aAAa;AACnE,MAAA,KAAA,MAAW,WAAW,CAAA,EAAG;AACvB,QAAA,MAAM,GAAA,GAAM,WAAA,CAAY,QAAA,CAAS,OAAO,CAAA;AAExC,QAAA,IAAI,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA,EAAG;AACrB,UAAA,MAAM;AAAA,YACJ,MAAM,EAAC;AAAA,YACP,WAAA,EAAa,OAAA;AAAA,YACb,YAAA,EAAc,QAAA;AAAA,YACd,QAAA;AAAA,YACA,OAAA,EAAS;AAAA,cACP,IAAA,EAAM,aAAA;AAAA,cACN,cAAc,WAAA,CAAY;AAAA;AAC5B,WACF;AAEA,UAAA,OAAO,GAAA,CAAI,KAAA;AAAA,QACb;AAAA,MACF;AAAA,IACF,CAAC,CAAA;AAED,IAAA,IAAI,GAAA,CAAI,UAAA,CAAW,MAAM,CAAA,EAAG;AAC1B,MAAA,OAAO,MAAA,CAAO,IAAI,MAAM,CAAA;AAAA,IAC1B;AAEA,IAAA,OAAO,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,EACpB,CAAA;AAEA,EAAA,MAAM,IAAA,GAAwB,CAAC,CAAA,KAC7B,CAAC,MAAM,CAAC,CAAA,GACJ,eAAA,EAAgB,GAChB,IAAI,GAAA,CAAI,MAAM,IAAA,CAAK,CAAC,EAAE,MAAA,CAAO,CAAC,MAAM,WAAA,CAAY,EAAA,CAAG,CAAC,CAAC,CAAC,CAAA;AAE5D,EAAA,MAAM,QAAQ,CAAC,CAAA;AAAA;AAAA,IAEb,IAAI,GAAA,CAAI,KAAA,CAAM,IAAA,CAAK,CAAA,EAAG,CAAC,CAAA,KAAM,WAAA,CAAY,KAAA,CAAM,CAAC,CAAC,CAAC;AAAA,GAAA;AAEpD,EAAA,OAAO;AAAA,IACL,QAAA;AAAA,IACA,IAAI,YAAA,GAAe;AACjB,MAAA,OAAO,eAAA,EAAgB;AAAA,IACzB,CAAA;AAAA,IACA,IAAA;AAAA,IACA,KAAA;AAAA,IACA,QAAA;AAAA,IACA,EAAA,EAAI,WAAW,QAAQ,CAAA;AAAA,IACvB,QAAA,EAAU,eAAe,QAAQ,CAAA;AAAA,IACjC,IAAA,EAAM,aAAa,QAAQ;AAAA,GAC7B;AACF;;;;"}