{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeApplications #-} {-| Module : Foreign.Lua.Module.Text Copyright : © 2017–2020 Albert Krewinkel License : MIT Maintainer : Albert Krewinkel Stability : alpha Portability : ForeignFunctionInterface Provide a lua module containing a selection of useful Text functions. -} module Foreign.Lua.Module.Text ( -- * Module pushModule , preloadModule , documentedModule , description , functions -- * Legacy , pushModuleText , preloadTextModule ) where import Prelude hiding (reverse) import Control.Applicative ((<$>)) import Data.ByteString (ByteString) import Data.Text (Text) import Data.Maybe (fromMaybe) import Foreign.Lua (NumResults, Lua, Peekable, Pushable, ToHaskellFunction) import Foreign.Lua.Call import Foreign.Lua.Module hiding (preloadModule, pushModule) import Foreign.Lua.Peek (Peeker, peekIntegral, peekText) import Foreign.Lua.Push (pushIntegral, pushText) import qualified Foreign.Lua as Lua import qualified Data.Text as T import qualified Foreign.Lua.Module as Module -- -- Module -- -- | Textual description of the "text" module. description :: Text description = "UTF-8 aware text manipulation functions, implemented in Haskell." documentedModule :: Module documentedModule = Module { moduleName = "paths" , moduleFields = [] , moduleDescription = description , moduleFunctions = functions } -- | Pushes the @text@ module to the Lua stack. pushModule :: Lua NumResults pushModule = 1 <$ Module.pushModule documentedModule pushModuleText :: Lua NumResults pushModuleText = 1 <$ Module.pushModule documentedModule -- | Add the @text@ module under the given name to the table of -- preloaded packages. preloadModule :: String -> Lua () preloadModule name = Module.preloadModule $ documentedModule { moduleName = T.pack name } -- | Add the text module under the given name to the table of preloaded -- packages. preloadTextModule :: String -> Lua () preloadTextModule = flip Lua.preloadhs pushModuleText -- -- Functions -- functions :: [(Text, HaskellFunction)] functions = [ ("len", len) , ("lower", lower) , ("reverse", reverse) , ("sub", sub) , ("upper", upper) ] -- | Wrapper for @'T.length'@. len :: HaskellFunction len = toHsFnPrecursor T.length <#> textParam "s" =#> intResult "length" #? "Determines the number of characters in a string." -- | Wrapper for @'T.toLower'@. lower :: HaskellFunction lower = toHsFnPrecursor T.toLower <#> textParam "s" =#> textResult "Lowercase copy of `s`" #? "Convert a string to lower case" -- | Wrapper for @'T.reverse'@. reverse :: HaskellFunction reverse = toHsFnPrecursor T.reverse <#> textParam "s" =#> textResult "Reversed `s`" #? "Reverses a string." -- | Returns a substring, using Lua's string indexing rules. sub :: HaskellFunction sub = toHsFnPrecursor substring <#> textParam "s" <#> textIndex "i" "substring start position" <#> textOptionalIndex "j" "substring end position" =#> textResult "text substring" #? "Returns a substring, using Lua's string indexing rules." where substring :: Text -> Int -> Maybe Int -> Text substring s i jopt = let j = fromMaybe (-1) jopt fromStart = if i >= 0 then i - 1 else T.length s + i fromEnd = if j < 0 then -j - 1 else T.length s - j in T.dropEnd fromEnd . T.drop fromStart $ s -- | Wrapper for @'T.toUpper'@. upper :: HaskellFunction upper = toHsFnPrecursor T.toUpper <#> textParam "s" =#> textResult "Lowercase copy of `s`" #? "Convert a string to lower case" -- -- Parameters -- textParam :: Text -> Parameter Text textParam name = parameter peekText "string" name "UTF-8 encoded string" textIndex :: Text -> Text -> Parameter Int textIndex = parameter (peekIntegral @Int) "integer" textOptionalIndex :: Text -> Text -> Parameter (Maybe Int) textOptionalIndex = optionalParameter (peekIntegral @Int) "integer" -- -- Results -- textResult :: Text -- ^ Description -> FunctionResults Text textResult = functionResult pushText "string" intResult :: Text -- ^ Description -> FunctionResults Int intResult = functionResult (pushIntegral @Int) "integer"