88 lines
1.9 KiB
Elm
88 lines
1.9 KiB
Elm
|
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
|
||
|
|
||
|
|
||
|
toSearchQuery : String -> String -> ( String, SearchQuery )
|
||
|
toSearchQuery name query =
|
||
|
( name, SearchQuery <| String.replace "%20" "+" <| Url.percentEncode query )
|
||
|
|
||
|
|
||
|
{-| 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
|
||
|
)
|
||
|
)
|