URI support (#59)

This commit is contained in:
Patrick Stevens
2024-01-03 19:47:59 +00:00
committed by GitHub
parent 7b3bd32323
commit ad2eeaaa4f
7 changed files with 100 additions and 0 deletions

View File

@@ -944,3 +944,27 @@ module Sessions =
Summary = Summary Summary = Summary
Visits = Visits Visits = Visits
} }
namespace PureGym
/// Module containing JSON parsing methods for the UriThing type
[<RequireQualifiedAccess>]
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module UriThing =
/// Parse from a JSON node.
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : UriThing =
let SomeUri =
(match node.["someUri"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("someUri")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
|> System.Uri
{
SomeUri = SomeUri
}

View File

@@ -180,6 +180,36 @@ module PureGymApi =
} }
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct)) |> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
member _.GetUrl (ct : CancellationToken option) =
async {
let! ct = Async.CancellationToken
let uri =
System.Uri (
(match client.BaseAddress with
| null -> System.Uri "https://whatnot.com"
| v -> v),
System.Uri ("some/url", System.UriKind.Relative)
)
let httpMessage =
new System.Net.Http.HttpRequestMessage (
Method = System.Net.Http.HttpMethod.Get,
RequestUri = uri
)
let! response = client.SendAsync (httpMessage, ct) |> Async.AwaitTask
let response = response.EnsureSuccessStatusCode ()
let! stream = response.Content.ReadAsStreamAsync ct |> Async.AwaitTask
let! node =
System.Text.Json.Nodes.JsonNode.ParseAsync (stream, cancellationToken = ct)
|> Async.AwaitTask
return UriThing.jsonParse node
}
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
member _.GetSessions (fromDate : DateOnly, toDate : DateOnly, ct : CancellationToken option) = member _.GetSessions (fromDate : DateOnly, toDate : DateOnly, ct : CancellationToken option) =
async { async {
let! ct = Async.CancellationToken let! ct = Async.CancellationToken

View File

@@ -177,3 +177,9 @@ type Sessions =
[<JsonPropertyName "Visits">] [<JsonPropertyName "Visits">]
Visits : Visit list Visits : Visit list
} }
[<WoofWare.Myriad.Plugins.JsonParse>]
type UriThing =
{
SomeUri : Uri
}

View File

@@ -26,6 +26,9 @@ type IPureGymApi =
[<GetAttribute "v1/member/activity">] [<GetAttribute "v1/member/activity">]
abstract GetMemberActivity : ?ct : CancellationToken -> Task<MemberActivityDto> abstract GetMemberActivity : ?ct : CancellationToken -> Task<MemberActivityDto>
[<Get "some/url">]
abstract GetUrl : ?ct : CancellationToken -> Task<UriThing>
// We'll use this one to check handling of absolute URIs too // We'll use this one to check handling of absolute URIs too
[<Get "/v2/gymSessions/member">] [<Get "/v2/gymSessions/member">]
abstract GetSessions : abstract GetSessions :

View File

@@ -236,3 +236,27 @@ module TestPureGymRestApi =
let api = PureGymApi.make client let api = PureGymApi.make client
api.GetSessions(startDate, endDate).Result |> shouldEqual expected api.GetSessions(startDate, endDate).Result |> shouldEqual expected
[<Test>]
let ``URI example`` () =
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
async {
message.Method |> shouldEqual HttpMethod.Get
message.RequestUri.ToString () |> shouldEqual "https://whatnot.com/some/url"
let content =
new StringContent ("""{"someUri": "https://patrick@en.wikipedia.org/wiki/foo"}""")
let resp = new HttpResponseMessage (HttpStatusCode.OK)
resp.Content <- content
return resp
}
use client = HttpClientMock.makeNoUri proc
let api = PureGymApi.make client
let uri = api.GetUrl().Result.SomeUri
uri.ToString () |> shouldEqual "https://patrick@en.wikipedia.org/wiki/foo"
uri.UserInfo |> shouldEqual "patrick"
uri.Host |> shouldEqual "en.wikipedia.org"

View File

@@ -423,6 +423,15 @@ module internal SynTypePatterns =
| _ -> None | _ -> None
| _ -> None | _ -> None
let (|Uri|_|) (fieldType : SynType) =
match fieldType with
| SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) ->
match ident |> List.map (fun i -> i.idText) with
| [ "System" ; "Uri" ]
| [ "Uri" ] -> Some ()
| _ -> None
| _ -> None
let (|Task|_|) (fieldType : SynType) : SynType option = let (|Task|_|) (fieldType : SynType) : SynType option =
match fieldType with match fieldType with
| SynType.App (SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)), _, args, _, _, _, _) -> | SynType.App (SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)), _, args, _, _, _, _) ->

View File

@@ -136,6 +136,10 @@ module internal JsonParseGenerator =
|> SynExpr.pipeThroughFunction ( |> SynExpr.pipeThroughFunction (
SynExpr.CreateLongIdent (SynLongIdent.Create [ "System" ; "DateOnly" ; "Parse" ]) SynExpr.CreateLongIdent (SynLongIdent.Create [ "System" ; "DateOnly" ; "Parse" ])
) )
| Uri ->
node
|> asValueGetValue propertyName "string"
|> SynExpr.pipeThroughFunction (SynExpr.CreateLongIdent (SynLongIdent.Create [ "System" ; "Uri" ]))
| DateTime -> | DateTime ->
node node
|> asValueGetValue propertyName "string" |> asValueGetValue propertyName "string"