2020-10-28 18:51:01 +00:00
|
|
|
module Route.SearchQuery exposing
|
|
|
|
( RawQuery
|
|
|
|
, SearchQuery
|
|
|
|
, absolute
|
|
|
|
, searchQueryToString
|
|
|
|
, searchString
|
|
|
|
, toRawQuery
|
|
|
|
, toSearchQuery
|
|
|
|
)
|
|
|
|
|
|
|
|
import Dict exposing (Dict)
|
|
|
|
import Url
|
|
|
|
import Url.Builder
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- RawQuery
|
|
|
|
|
|
|
|
|
|
|
|
type RawQuery
|
|
|
|
= RawQuery (Dict String String)
|
|
|
|
|
|
|
|
|
|
|
|
chunk : String -> String -> Maybe ( String, String )
|
|
|
|
chunk sep str =
|
|
|
|
case String.split sep str of
|
|
|
|
[] ->
|
|
|
|
Nothing
|
|
|
|
|
|
|
|
[ key ] ->
|
|
|
|
Just ( key, "" )
|
|
|
|
|
|
|
|
key :: xs ->
|
|
|
|
Just ( key, String.join sep xs )
|
|
|
|
|
|
|
|
|
|
|
|
toRawQuery : Url.Url -> Maybe RawQuery
|
|
|
|
toRawQuery =
|
|
|
|
Maybe.map (RawQuery << Dict.fromList << List.filterMap (chunk "=") << String.split "&")
|
|
|
|
<< .query
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- SearchQuery
|
|
|
|
|
|
|
|
|
|
|
|
{-| This is type safe wrapper for working with search queries in url
|
|
|
|
-}
|
|
|
|
type SearchQuery
|
|
|
|
= SearchQuery String
|
|
|
|
|
|
|
|
|
|
|
|
searchString : String -> RawQuery -> Maybe SearchQuery
|
|
|
|
searchString name (RawQuery dict) =
|
|
|
|
Maybe.map SearchQuery <| Dict.get name dict
|
|
|
|
|
|
|
|
|
|
|
|
searchQueryToString : SearchQuery -> Maybe String
|
|
|
|
searchQueryToString (SearchQuery str) =
|
|
|
|
Url.percentDecode <| String.replace "+" "%20" str
|
|
|
|
|
|
|
|
|
2020-10-30 18:13:55 +00:00
|
|
|
toSearchQuery : String -> SearchQuery
|
|
|
|
toSearchQuery query =
|
|
|
|
SearchQuery <| String.replace "%20" "+" <| Url.percentEncode query
|
2020-10-28 18:51:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
{-| Build absolute URL with support for search query strings
|
|
|
|
-}
|
|
|
|
absolute : List String -> List Url.Builder.QueryParameter -> List ( String, SearchQuery ) -> String
|
|
|
|
absolute path query searchQuery =
|
|
|
|
let
|
|
|
|
searchStrings =
|
|
|
|
List.map (\( name, SearchQuery val ) -> name ++ "=" ++ val) searchQuery
|
|
|
|
|> String.join "&"
|
|
|
|
in
|
|
|
|
Url.Builder.absolute path query
|
|
|
|
|> (\str ->
|
|
|
|
str
|
|
|
|
++ (case query of
|
|
|
|
[] ->
|
|
|
|
"?" ++ searchStrings
|
|
|
|
|
|
|
|
_ ->
|
|
|
|
"&" ++ searchStrings
|
|
|
|
)
|
|
|
|
)
|