11{-# LANGUAGE OverloadedStrings #-}
2+ {-# LANGUAGE TypeApplications #-}
23{-|
34Module : Foreign.Lua.Module.Text
4- Copyright : © 2017–2019 Albert Krewinkel
5+ Copyright : © 2017–2020 Albert Krewinkel
56License : MIT
67Maintainer : Albert Krewinkel <[email protected] > 78Stability : alpha
@@ -10,44 +11,147 @@ Portability : ForeignFunctionInterface
1011Provide a lua module containing a selection of useful Text functions.
1112-}
1213module Foreign.Lua.Module.Text
13- ( pushModule
14+
15+ ( -- * Module
16+ pushModule
17+ , preloadModule
18+ , documentedModule
19+ , description
20+ , functions
21+
22+ -- * Legacy
1423 , pushModuleText
1524 , preloadTextModule
16- )where
25+ ) where
1726
27+ import Prelude hiding (reverse )
1828import Control.Applicative ((<$>) )
1929import Data.ByteString (ByteString )
2030import Data.Text (Text )
2131import Data.Maybe (fromMaybe )
2232import Foreign.Lua (NumResults , Lua , Peekable , Pushable , ToHaskellFunction )
33+ import Foreign.Lua.Call
34+ import Foreign.Lua.Module hiding (preloadModule , pushModule )
35+ import Foreign.Lua.Peek (Peeker , peekIntegral , peekText )
36+ import Foreign.Lua.Push (pushIntegral , pushText )
2337import qualified Foreign.Lua as Lua
2438import qualified Data.Text as T
2539
40+ import qualified Foreign.Lua.Module as Module
41+ --
42+ -- Module
43+ --
44+
45+ -- | Textual description of the "text" module.
46+ description :: Text
47+ description =
48+ " UTF-8 aware text manipulation functions, implemented in Haskell."
49+
50+ documentedModule :: Module
51+ documentedModule = Module
52+ { moduleName = " paths"
53+ , moduleFields = []
54+ , moduleDescription = description
55+ , moduleFunctions = functions
56+ }
57+
2658-- | Pushes the @text@ module to the Lua stack.
2759pushModule :: Lua NumResults
28- pushModule = do
29- Lua. newtable
30- Lua. addfunction " lower" (return . T. toLower :: Text -> Lua Text )
31- Lua. addfunction " upper" (return . T. toUpper :: Text -> Lua Text )
32- Lua. addfunction " reverse" (return . T. reverse :: Text -> Lua Text )
33- Lua. addfunction " len" (return . fromIntegral . T. length :: Text -> Lua Lua. Integer )
34- Lua. addfunction " sub" sub
35- return 1
36-
37- -- | Legacy alias for '@pushModule@'.
60+ pushModule = 1 <$ Module. pushModule documentedModule
61+
3862pushModuleText :: Lua NumResults
39- pushModuleText = pushModule
63+ pushModuleText = 1 <$ Module. pushModule documentedModule
64+
65+ -- | Add the @text@ module under the given name to the table of
66+ -- preloaded packages.
67+ preloadModule :: String -> Lua ()
68+ preloadModule name = Module. preloadModule $
69+ documentedModule { moduleName = T. pack name }
4070
4171-- | Add the text module under the given name to the table of preloaded
4272-- packages.
4373preloadTextModule :: String -> Lua ()
44- preloadTextModule = flip Lua. preloadhs pushModule
74+ preloadTextModule = flip Lua. preloadhs pushModuleText
75+
76+ --
77+ -- Functions
78+ --
79+
80+ functions :: [(Text , HaskellFunction )]
81+ functions =
82+ [ (" len" , len)
83+ , (" lower" , lower)
84+ , (" reverse" , reverse )
85+ , (" sub" , sub)
86+ , (" upper" , upper)
87+ ]
88+
89+ -- | Wrapper for @'T.length'@.
90+ len :: HaskellFunction
91+ len = toHsFnPrecursor T. length
92+ <#> textParam " s"
93+ =#> intResult " length"
94+ #? " Determines the number of characters in a string."
95+
96+ -- | Wrapper for @'T.toLower'@.
97+ lower :: HaskellFunction
98+ lower = toHsFnPrecursor T. toLower
99+ <#> textParam " s"
100+ =#> textResult " Lowercase copy of `s`"
101+ #? " Convert a string to lower case"
102+
103+ -- | Wrapper for @'T.reverse'@.
104+ reverse :: HaskellFunction
105+ reverse = toHsFnPrecursor T. reverse
106+ <#> textParam " s"
107+ =#> textResult " Reversed `s`"
108+ #? " Reverses a string."
45109
46110-- | Returns a substring, using Lua's string indexing rules.
47- sub :: Text -> Lua. Integer -> Lua. Optional Lua. Integer -> Lua Text
48- sub s i j =
49- let i' = fromIntegral i
50- j' = fromIntegral . fromMaybe (- 1 ) $ Lua. fromOptional j
51- fromStart = if i' >= 0 then i' - 1 else T. length s + i'
52- fromEnd = if j' < 0 then - j' - 1 else T. length s - j'
53- in return . T. dropEnd fromEnd . T. drop fromStart $ s
111+ sub :: HaskellFunction
112+ sub = toHsFnPrecursor substring
113+ <#> textParam " s"
114+ <#> textIndex " i" " substring start position"
115+ <#> textOptionalIndex " j" " substring end position"
116+ =#> textResult " text substring"
117+ #? " Returns a substring, using Lua's string indexing rules."
118+ where
119+ substring :: Text -> Int -> Maybe Int -> Text
120+ substring s i jopt =
121+ let j = fromMaybe (- 1 ) jopt
122+ fromStart = if i >= 0 then i - 1 else T. length s + i
123+ fromEnd = if j < 0 then - j - 1 else T. length s - j
124+ in T. dropEnd fromEnd . T. drop fromStart $ s
125+
126+ -- | Wrapper for @'T.toUpper'@.
127+ upper :: HaskellFunction
128+ upper = toHsFnPrecursor T. toUpper
129+ <#> textParam " s"
130+ =#> textResult " Lowercase copy of `s`"
131+ #? " Convert a string to lower case"
132+
133+ --
134+ -- Parameters
135+ --
136+
137+ textParam :: Text -> Parameter Text
138+ textParam name =
139+ parameter peekText " string" name " UTF-8 encoded string"
140+
141+ textIndex :: Text -> Text -> Parameter Int
142+ textIndex = parameter (peekIntegral @ Int ) " integer"
143+
144+ textOptionalIndex :: Text -> Text -> Parameter (Maybe Int )
145+ textOptionalIndex = optionalParameter (peekIntegral @ Int ) " integer"
146+
147+ --
148+ -- Results
149+ --
150+
151+ textResult :: Text -- ^ Description
152+ -> FunctionResults Text
153+ textResult = functionResult pushText " string"
154+
155+ intResult :: Text -- ^ Description
156+ -> FunctionResults Int
157+ intResult = functionResult (pushIntegral @ Int ) " integer"
0 commit comments