Add a oneOf matcher.

This commit is contained in:
Dillon Kearns 2021-03-30 15:37:03 -07:00
parent 6983dd582b
commit b80a59e2fc
2 changed files with 97 additions and 40 deletions

View File

@ -1,13 +1,19 @@
module Glob exposing (..) module Glob exposing (..)
import List.Extra
type Glob a type Glob a
= Glob String (List String -> a) = Glob String (List String -> a)
type GlobMatcher type GlobMatcher a
= Literal String = GlobMatcher String (CaptureToValue a)
| Star
type CaptureToValue a
= Hardcoded a
| Dynamic (String -> a)
init : constructor -> Glob constructor init : constructor -> Glob constructor
@ -17,7 +23,10 @@ init constructor =
run : List String -> Glob a -> { match : a, pattern : String } run : List String -> Glob a -> { match : a, pattern : String }
run captures (Glob pattern applyCapture) = run captures (Glob pattern applyCapture) =
{ match = applyCapture captures { match =
captures
|> List.reverse
|> applyCapture
, pattern = pattern , pattern = pattern
} }
@ -27,63 +36,89 @@ toPattern (Glob pattern applyCapture) =
pattern pattern
keep : GlobMatcher -> Glob (String -> value) -> Glob value keep : GlobMatcher a -> Glob (a -> value) -> Glob value
keep matcher (Glob pattern applyCapture) = keep (GlobMatcher matcherPattern toValue) (Glob pattern applyCapture) =
Glob (pattern ++ matcherToPattern matcher) Glob (pattern ++ matcherPattern)
(case matcher of (case toValue of
Literal literalString -> Hardcoded value ->
continueNonCapturing literalString applyCapture continueNonCapturing value applyCapture
Star -> Dynamic toValueFn ->
popCapture applyCapture popCapture toValueFn applyCapture
) )
matcherToPattern : GlobMatcher -> String continueNonCapturing : a -> (List String -> (a -> value)) -> (List String -> value)
matcherToPattern matcher =
case matcher of
Literal literalString ->
literalString
Star ->
"*"
continueNonCapturing : String -> (List String -> (String -> value)) -> (List String -> value)
continueNonCapturing hardcodedCaptureValue applyCapture = continueNonCapturing hardcodedCaptureValue applyCapture =
\captures -> \captures ->
applyCapture captures hardcodedCaptureValue applyCapture captures hardcodedCaptureValue
popCapture : (List String -> (String -> value)) -> (List String -> value) popCapture : (String -> a) -> (List String -> (a -> value)) -> (List String -> value)
popCapture applyCapture = popCapture toValueFn applyCapture =
\captures -> \captures ->
let
_ =
Debug.log "pop" captures
in
case captures of case captures of
first :: rest -> first :: rest ->
applyCapture rest first applyCapture rest (toValueFn first)
[] -> [] ->
applyCapture [] "ERROR" --applyCapture [] (toValueFn "ERROR")
Debug.todo "Ran out of items"
drop : GlobMatcher -> Glob a -> Glob a drop : GlobMatcher a -> Glob value -> Glob value
drop matcher (Glob pattern applyCapture) = drop (GlobMatcher matcherPattern toValue) (Glob pattern applyCapture) =
Glob (pattern ++ matcherToPattern matcher) Glob
(\captures -> (pattern ++ matcherPattern)
case matcher of (case toValue of
Literal literalString -> Hardcoded value ->
applyCapture captures applyCapture
Star -> Dynamic toValueFn ->
applyCapture captures \captures ->
applyCapture (captures |> List.drop 1)
) )
literal : String -> GlobMatcher oneOf : ( ( String, a ), List ( String, a ) ) -> GlobMatcher a
oneOf ( defaultMatch, otherMatchers ) =
let
allMatchers =
defaultMatch :: otherMatchers
in
GlobMatcher
("{"
++ (allMatchers |> List.map Tuple.first |> String.join ",")
++ "}"
)
(Dynamic
(\match ->
allMatchers
|> List.Extra.findMap
(\( literalString, result ) ->
if
(literalString |> Debug.log "lhs")
== (match |> Debug.log "rhs")
then
Just result
else
Nothing
)
|> Maybe.withDefault (defaultMatch |> Tuple.second)
)
)
literal : String -> GlobMatcher String
literal string = literal string =
Literal string GlobMatcher string (Hardcoded string)
star : GlobMatcher star : GlobMatcher String
star = star =
Star GlobMatcher "*" (Dynamic identity)

View File

@ -26,9 +26,31 @@ all =
, expectedMatch = "my-file" , expectedMatch = "my-file"
, expectedPattern = "*.txt" , expectedPattern = "*.txt"
} }
, test "oneOf" <|
\() ->
Glob.init Tuple.pair
|> Glob.keep Glob.star
|> Glob.drop (Glob.literal ".")
|> Glob.keep
(Glob.oneOf
( ( "yml", Yml )
, [ ( "json", Json )
]
)
)
|> expect
{ captures = [ "data-file", "json" ]
, expectedMatch = ( "data-file", Json )
, expectedPattern = "*.{yml,json}"
}
] ]
type DataExtension
= Yml
| Json
expect : expect :
{ captures : List String { captures : List String
, expectedMatch : match , expectedMatch : match