Files
puregym-unofficial-dotnet/PureGym/GymSelector.fs
patrick 419f27053f
All checks were successful
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/push/all-checks-complete Pipeline was successful
Add all-gyms (#11)
Co-authored-by: Smaug123 <patrick+github@patrickstevens.co.uk>
Reviewed-on: #11
2024-02-12 22:08:02 +00:00

53 lines
1.8 KiB
Forth

namespace PureGym
open System.Threading.Tasks
open Fastenshtein
/// Identifies a gym, possibly non-uniquely and possibly ambiguously.
[<RequireQualifiedAccess>]
type GymSelector =
/// The ID of this gym, according to the PureGym internal mapping.
| Id of int
/// The user-specified name of this gym.
| Name of string
/// The home gym of the authenticated user.
| Home
/// Methods for manipulating GymSelector.
[<RequireQualifiedAccess>]
module GymSelector =
/// Get the canonical PureGym ID for this user-specified gym.
let canonicalId (client : IPureGymApi) (gym : GymSelector) : int Task =
match gym with
| GymSelector.Home ->
async {
let! ct = Async.CancellationToken
let! self = Async.AwaitTask (client.GetMember ct)
return self.HomeGymId
}
|> Async.StartAsTask
| GymSelector.Id i -> Task.FromResult<_> i
| GymSelector.Name name ->
async {
let! ct = Async.CancellationToken
let! allGyms = Async.AwaitTask (client.GetGyms ct)
if allGyms.IsEmpty then
return failwith "PureGym API returned no gyms!"
else
let distance = Levenshtein (name.ToLowerInvariant ())
let bestDistance, bestGym =
allGyms
|> Seq.map (fun gym -> distance.DistanceFrom (gym.Name.ToLowerInvariant ()), gym)
|> Seq.sortBy fst
|> Seq.head
if bestDistance <> 0 then
System.Console.Error.WriteLine $"Autocorrected gym from %s{name} to %s{bestGym.Name}"
return bestGym.Id
}
|> Async.StartAsTask