Helper functions to make basic cofig
Helper function to create a getFilterKeys
function out of a static list of matches.
Helper function to create a getFilterValues
function out of a static dictionary of matches.
The sample list of matches regardless of current text
Basic matching using current text as a regex
Same as basic matching but case insensitive
module FilterBox.Helpers exposing (simple, basic, caseInsensitive, getKeys, getValues)
{-| Helper functions to make basic cofig
# Getters
@docs getKeys, getValues
# Matchers
@docs simple, basic, caseInsensitive
-}
import Dict exposing (Dict)
import FilterBox exposing (InputMatch)
import List.Extra exposing (last)
import Regex exposing (HowMany(..), Match, find, regex)
import Task exposing (Task)
{-| Helper function to create a `getFilterKeys` function out of a static list of matches.
-}
getKeys : (String -> List String -> List InputMatch) -> List String -> (String -> Task String (List InputMatch))
getKeys matchFunction possibleMatches =
(\key ->
matchFunction key possibleMatches
|> withDefault (List.take 3 possibleMatches)
|> Task.succeed
)
{-| Helper function to create a `getFilterValues` function out of a static dictionary of matches.
-}
getValues :
(String -> List String -> List InputMatch)
-> Dict String (List String)
-> (String -> String -> Task String (List InputMatch))
getValues matchFunction possibleMatchesDict =
(\key value ->
let
possibleMatches =
Dict.get (String.toLower key) possibleMatchesDict
|> Maybe.withDefault []
in
possibleMatches
|> matchFunction value
|> withDefault (List.take 3 possibleMatches)
|> Task.succeed
)
withDefault : List String -> List InputMatch -> List InputMatch
withDefault default matches =
case matches of
[] ->
List.map inputMatchFromString default
m ->
m
inputMatchFromString : String -> InputMatch
inputMatchFromString string =
{ match = [ ( string, False ) ]
, description = Nothing
}
{-| The sample list of matches regardless of current text
-}
simple : String -> List String -> List InputMatch
simple _ possibleMatches =
List.map
(\m ->
{ match = [ ( m, False ) ]
, description = Nothing
}
)
possibleMatches
{-| Basic matching using current text as a regex
-}
basic : String -> List String -> List InputMatch
basic string possibleMatches =
possibleMatches
|> List.map (\p -> ( p, find (AtMost 1) (regex string) p ))
|> regexMatchesToInputMatches
{-| Same as basic matching but case insensitive
-}
caseInsensitive : String -> List String -> List InputMatch
caseInsensitive string possibleMatches =
possibleMatches
|> List.map (\p -> ( p, find (AtMost 1) (Regex.caseInsensitive <| regex string) p ))
|> regexMatchesToInputMatches
regexMatchesToInputMatches : List ( String, List Match ) -> List InputMatch
regexMatchesToInputMatches regexMatches =
regexMatches
|> List.sortBy
(\( p, matches ) ->
List.head matches
|> Maybe.map .index
|> Maybe.withDefault 1000000
)
|> List.map
(\( p, matches ) ->
( p
, List.map
(\match ->
( match.index, match.index + String.length match.match, True )
)
matches
)
)
|> List.filterMap
(\( p, matches ) ->
case List.head matches of
Nothing ->
Nothing
Just ( 0, 0, _ ) ->
Nothing
Just ( start, end, _ ) ->
Just ( p, List.append [ ( 0, start, False ) ] matches )
)
|> List.filterMap
(\( p, matches ) ->
case last matches of
Nothing ->
Nothing
Just ( 0, 0, _ ) ->
Nothing
Just ( start, end, _ ) ->
Just ( p, List.append matches [ ( end, String.length p, False ) ] )
)
|> List.map
(\( p, matches ) ->
List.map (\( start, end, match ) -> ( String.slice start end p, match )) matches
)
|> List.map (\m -> { match = m, description = Nothing })