aux-search/src/Route/SearchQuery.elm

88 lines
1.9 KiB
Elm
Raw Normal View History

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
)
)