53 lines
1.8 KiB
Forth
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
|