Skip to content

Commit

Permalink
#1035 #1050 fix server-side inferred router union case parse order
Browse files Browse the repository at this point in the history
  • Loading branch information
Jand42 committed Mar 13, 2019
1 parent 3d555f9 commit 5c2d30a
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 6 deletions.
40 changes: 34 additions & 6 deletions src/sitelets/WebSharper.Sitelets/InferredRouter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ module internal ServerInferredOperators =
Some (box s)
| _ -> None
| [] ->
Some (box "")
None
IWrite = fun (w, value) ->
if isNull value then
w.NextSegment().Append("null") |> ignore
Expand All @@ -191,6 +191,16 @@ module internal ServerInferredOperators =
IExplicitMethods = Set.empty
}

let internal iEmptyString : InferredRouter =
{ iString with
IParse = fun path ->
match path.Segments with
| [] ->
Some (box "")
| _ ->
None
}

let internal iChar : InferredRouter =
{
IParse = fun path ->
Expand Down Expand Up @@ -711,9 +721,27 @@ module internal ServerInferredOperators =
let parseWithOrWithoutWildcards useWildcards =

let lookupCasesByMethod =
cases |> Seq.indexed |> Seq.collect (fun (i, c) ->
cases |> Seq.indexed
|> Seq.collect (fun (i, c) ->
// for cases ending with any number of field segments, generate extra parses cases
// where they are all parsing empty strings from reaching the end of a route
let fieldsLength = c.Fields.Length
Some (List.rev (List.ofArray c.Fields), 0)
|> List.unfold (
function
| Some (f, e) ->
let case =
i, c, List.rev (List.replicate e iEmptyString @ f), fieldsLength - e
match f with
| h :: t when h = iString ->
Some (case, Some (t, e + 1))
| _ ->
Some (case, None)
| None -> None
)
)
|> Seq.collect (fun (i, c, fieldList, fieldsLength) ->
if c.HasWildCard && not useWildcards then Seq.empty else
let fieldList = List.ofArray c.Fields
let l = c.Fields.Length
let parseFields p path =
let arr = Array.zeroCreate l
Expand Down Expand Up @@ -746,7 +774,7 @@ module internal ServerInferredOperators =
-1,
fun p path -> Some c
| _ ->
fieldList.Length - 1, parseFields
fieldsLength - 1, parseFields
| [ h ] ->
h,
match fieldList with
Expand All @@ -757,7 +785,7 @@ module internal ServerInferredOperators =
path.Segments <- p
Some c
| _ ->
fieldList.Length, parseFields
fieldsLength, parseFields
| h :: t ->
h,
match fieldList with
Expand All @@ -771,7 +799,7 @@ module internal ServerInferredOperators =
Some c
| None -> None
| _ ->
t.Length + fieldList.Length,
t.Length + fieldsLength,
fun p path ->
match p |> List.startsWith t with
| Some p -> parseFields p path
Expand Down
10 changes: 10 additions & 0 deletions tests/WebSharper.Web.Tests/Routers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ module PerformanceTests =
| [<EndPoint "/record-with-queries">] URecordQ of RecQTest
| [<EndPoint "/list">] UList of list<int * string>
| [<EndPoint "/array">] UArray of (int * string)[]
| [<EndPoint "/priority">] UPriority1
| [<EndPoint "/priority">] UPriority2 of int
| [<EndPoint "/priority">] UPriority3 of string
| [<EndPoint "/priority">] UPriority4 of int * string
| [<EndPoint "/priority">] UPriority5 of string * string
| [<Method "POST"; EndPoint "/post">] UPost of int
| [<Method "PUT"; EndPoint "/put">] UPut of int
| [<EndPoint "POST /post2">] UPost2 of int
Expand Down Expand Up @@ -160,6 +165,11 @@ module PerformanceTests =
UString "xx", "/stringtoo/xx"
UCSharp (new CSharpEndPointRoot()), "/csharp/home"
UCSharp (new CSharpEndPointRoot.Sub1(X = 42)), "/csharp/sub1full/42"
UPriority1, "/priority"
UPriority2 123, "/priority/123"
UPriority3 "xx", "/priority/xx"
UPriority4 (123, "xx"), "/priority/123/xx"
UPriority5 ("xx", "yy"), "/priority/xx/yy"
]

let mutable expecting = None
Expand Down

0 comments on commit 5c2d30a

Please sign in to comment.