Skip to content

Commit

Permalink
feat(TypeSafeEnum): Add caseValues
Browse files Browse the repository at this point in the history
  • Loading branch information
bartelink committed Feb 22, 2024
1 parent ca01ebb commit a4fe3f1
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 2 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/FsCodec/TypeSafeEnum.fs
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,6 @@ let parseF<'T> f =
let parse<'T> = parseF<'T> (=)

let toString<'t> : 't -> string = Union.caseName<'t>

/// <summary>Yields all the cases available for <c>'t</c> which must be a <c>TypeSafeEnum</c></summary>
let caseValues<'t>: 't[] = Union.Info.caseValues<'t>
5 changes: 3 additions & 2 deletions src/FsCodec/Union.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit a4fe3f1

Please sign in to comment.