From a4fe3f12aad1f990eff57826795fc76950090676 Mon Sep 17 00:00:00 2001 From: Ruben Bartelink Date: Thu, 22 Feb 2024 17:09:24 +0000 Subject: [PATCH] feat(TypeSafeEnum): Add caseValues --- CHANGELOG.md | 5 +++++ src/FsCodec/TypeSafeEnum.fs | 3 +++ src/FsCodec/Union.fs | 5 +++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e027394..11997bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,11 @@ The `Unreleased` section name is replaced by the expected version of next releas ## [Unreleased] ### Added + +### Added + +- `TypeeSafeEnum.caseValues<'t>`: Yields all values of a Union + ### Changed ### Removed ### Fixed diff --git a/src/FsCodec/TypeSafeEnum.fs b/src/FsCodec/TypeSafeEnum.fs index 2b329c0..082a8d8 100755 --- a/src/FsCodec/TypeSafeEnum.fs +++ b/src/FsCodec/TypeSafeEnum.fs @@ -30,3 +30,6 @@ let parseF<'T> f = let parse<'T> = parseF<'T> (=) let toString<'t> : 't -> string = Union.caseName<'t> + +/// Yields all the cases available for 't which must be a TypeSafeEnum +let caseValues<'t>: 't[] = Union.Info.caseValues<'t> diff --git a/src/FsCodec/Union.fs b/src/FsCodec/Union.fs index 71f6600..b4ea797 100644 --- a/src/FsCodec/Union.fs +++ b/src/FsCodec/Union.fs @@ -26,10 +26,11 @@ module Info = let getCase value = cases[getTag value] { cases = cases; getCase = getCase }) let tryFindCaseWithName u (predicate: string -> bool): CaseInfo option = u.cases |> Array.tryFind (fun c -> predicate c.name) - let private caseValues: Type -> obj[] = memoize (fun t -> (get t).cases |> Array.map (fun c -> c.construct Array.empty)) + let caseValues<'t>: 't[] = (get typeof<'t>).cases |> Array.map (fun c -> c.construct Array.empty :?> 't) + let caseValuesT: Type -> obj[] = memoize (fun t -> (get t).cases |> Array.map (fun c -> c.construct Array.empty)) let tryFindCaseValueWithName (t: Type): (string -> bool) -> obj option = let u = get t - let caseValue = let values = caseValues t in fun i -> values[i] + let caseValue = let values = caseValuesT t in fun i -> values[i] fun predicate -> u.cases |> Array.tryFindIndex (fun c -> predicate c.name) |> Option.map caseValue /// Determines whether the type is a Union