Add a starting point for glob API.

This commit is contained in:
Dillon Kearns 2021-03-30 14:16:32 -07:00
parent b0d7f9c8ac
commit 6983dd582b
2 changed files with 134 additions and 0 deletions

89
src/Glob.elm Normal file
View File

@ -0,0 +1,89 @@
module Glob exposing (..)
type Glob a
= Glob String (List String -> a)
type GlobMatcher
= Literal String
| Star
init : constructor -> Glob constructor
init constructor =
Glob "" (\captures -> constructor)
run : List String -> Glob a -> { match : a, pattern : String }
run captures (Glob pattern applyCapture) =
{ match = applyCapture captures
, pattern = pattern
}
toPattern : Glob a -> String
toPattern (Glob pattern applyCapture) =
pattern
keep : GlobMatcher -> Glob (String -> value) -> Glob value
keep matcher (Glob pattern applyCapture) =
Glob (pattern ++ matcherToPattern matcher)
(case matcher of
Literal literalString ->
continueNonCapturing literalString applyCapture
Star ->
popCapture applyCapture
)
matcherToPattern : GlobMatcher -> String
matcherToPattern matcher =
case matcher of
Literal literalString ->
literalString
Star ->
"*"
continueNonCapturing : String -> (List String -> (String -> value)) -> (List String -> value)
continueNonCapturing hardcodedCaptureValue applyCapture =
\captures ->
applyCapture captures hardcodedCaptureValue
popCapture : (List String -> (String -> value)) -> (List String -> value)
popCapture applyCapture =
\captures ->
case captures of
first :: rest ->
applyCapture rest first
[] ->
applyCapture [] "ERROR"
drop : GlobMatcher -> Glob a -> Glob a
drop matcher (Glob pattern applyCapture) =
Glob (pattern ++ matcherToPattern matcher)
(\captures ->
case matcher of
Literal literalString ->
applyCapture captures
Star ->
applyCapture captures
)
literal : String -> GlobMatcher
literal string =
Literal string
star : GlobMatcher
star =
Star

45
tests/GlobTests.elm Normal file
View File

@ -0,0 +1,45 @@
module GlobTests exposing (all)
import Expect
import Glob
import Test exposing (describe, only, test)
all =
describe "glob"
[ test "literal" <|
\() ->
Glob.init identity
|> Glob.keep (Glob.literal "hello")
|> expect
{ captures = []
, expectedMatch = "hello"
, expectedPattern = "hello"
}
, test "capture" <|
\() ->
Glob.init identity
|> Glob.keep Glob.star
|> Glob.drop (Glob.literal ".txt")
|> expect
{ captures = [ "my-file" ]
, expectedMatch = "my-file"
, expectedPattern = "*.txt"
}
]
expect :
{ captures : List String
, expectedMatch : match
, expectedPattern : String
}
-> Glob.Glob match
-> Expect.Expectation
expect { captures, expectedMatch, expectedPattern } glob =
glob
|> Glob.run captures
|> Expect.equal
{ pattern = expectedPattern
, match = expectedMatch
}