diff options
author | Teddy Wing | 2017-07-30 16:45:59 +0200 |
---|---|---|
committer | Teddy Wing | 2017-07-30 16:45:59 +0200 |
commit | 4bb65c50a2a85404af6d122acc53b6fb1739652b (patch) | |
tree | 71475e85fe58e2bc364e4ba664be7cc3a3f855cb /src | |
parent | 55fed7804d686fed83d9265b7f574f9b5b9d6d3e (diff) | |
download | sorbot-4bb65c50a2a85404af6d122acc53b6fb1739652b.tar.bz2 |
Transform regex match into the beginning of a plugin architecture
Take our initial experiment on the regex matcher from before and expand
it into the beginnings of a plugin architecture.
Add a new `Plugin` module. This exports a `Plugin` data type that
collects a regex and a function together. The idea will be to create a
list of plugins, and chat messages will get matched against the regexes
in that list. If the regex matches, the associated function will be run.
If the function produces output, that output should eventually be sent
back to the chat as a message.
Implemented `Show` on `Plugin` manually because the `String -> String`
function can't be derived. Decided to forego that part in the output and
only show the regex when printing.
Ended up with a little redundancy here in the functions for matching
plugins. The `realMatchPlugin` function needs to be renamed, just called
it that for now because I had started with `matchPlugin`, and only later
realised that its interface wasn't what I needed when calling it from
the `Lib` module.
Need to add some doc comments, but figured I'd commit what I have now
since it sort of works.
The `firstPlugin` function is only used by `matchPlugin`, so now I
realise it should probably be a local `where`-defined function.
Also thought the `String -> String` wasn't very descriptive. We'll want
to make a type alias for that that tells people this is a plugin
function.
Added a test plugin inline in this file for now. Eventually our plugins
should be stored in separate files in a "Plugins" directory (or
"Plugin", depending on how the module system works, will have to look
into that). For now, the program outputs the correct string created by
`gitHubCommitAction`, which is actually pretty cool. It's not actually
the really correct string, as the `match` variable is the regex instead
of the matched part of the test string, but close enough for now. We'll
go back and correct that momentarily.
Needed to add `Plugin` to the `exposed-modules` section in the `library`
build metadata in order to properly build the code. Was getting this
error about it:
Warning: The following modules should be added to exposed-modules or other-modules in /Users/tw/Documents/Development/sorbot/sorbot/sorbot.cabal:
- In the library component:
Plugin
Missing modules in the cabal file are likely to cause undefined reference errors from the linker, along with other problems.
Really liking this so far!
Diffstat (limited to 'src')
-rw-r--r-- | src/Lib.hs | 12 | ||||
-rw-r--r-- | src/Plugin.hs | 46 |
2 files changed, 51 insertions, 7 deletions
@@ -4,11 +4,9 @@ module Lib import Text.Regex.TDFA -someFunc :: IO () -someFunc - | rex == True = putStrLn "Match!!" - | otherwise = putStrLn "No match" - +import Plugin -rex :: Bool -rex = "75ac7b18a009ffe7a77a17a61d95c01395f36b44" =~ "^[0-9a-f]{40}$" +someFunc :: IO () +someFunc = do + let Just plugin = realMatchPlugin "75ac7b18a009ffe7a77a17a61d95c01395f36b44" + putStrLn $ performPlugin plugin diff --git a/src/Plugin.hs b/src/Plugin.hs new file mode 100644 index 0000000..95f2461 --- /dev/null +++ b/src/Plugin.hs @@ -0,0 +1,46 @@ +module Plugin + ( realMatchPlugin + , Plugin + , performPlugin + , plugins + ) where + +import Text.Regex.TDFA + +data Plugin = Plugin + { matchRegex :: String + , perform :: String -> String + } + +instance Show Plugin where + show (Plugin r p) = "matchRegex = " ++ r + +realMatchPlugin :: String -> Maybe Plugin +realMatchPlugin message = matchPlugin message plugins + +matchPlugin :: String -> [Plugin] -> Maybe Plugin +matchPlugin message plugins = firstPlugin $ matchPlugins message plugins + +matchPlugins :: String -> [Plugin] -> [Plugin] +matchPlugins message plugins = [p | p <- plugins, message =~ matchRegex p] + +firstPlugin :: [Plugin] -> Maybe Plugin +firstPlugin [] = Nothing +firstPlugin (p:ps) = Just p + +-- TODO: Make a type for the `perform` function +performPlugin :: Plugin -> String +performPlugin p = perform p $ matchRegex p + +gitHubCommit = Plugin + { matchRegex = "^[0-9a-f]{40}$" + , perform = gitHubCommitAction + } + +gitHubCommitAction :: String -> String +gitHubCommitAction match = "https://github.com/" ++ match + +plugins :: [Plugin] +plugins = + [ gitHubCommit + ] |