This is an alternative site for discovering Elm packages. You may be looking for the official Elm package site instead.
README FilterBox

FilterBox.Helpers

Helper functions to make basic cofig

Getters

getKeys : (String -> List String -> List InputMatch) -> List String -> (String -> Task String (List InputMatch))

Helper function to create a getFilterKeys function out of a static list of matches.

getValues : (String -> List String -> List InputMatch) -> Dict String (List String) -> (String -> String -> Task String (List InputMatch))

Helper function to create a getFilterValues function out of a static dictionary of matches.

Matchers

simple : String -> List String -> List InputMatch

The sample list of matches regardless of current text

basic : String -> List String -> List InputMatch

Basic matching using current text as a regex

caseInsensitive : String -> List String -> List InputMatch

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