Commits

Anonymous committed c4e92aa

Adding functions to TH to make CamelCase to under_score easier.

I have noticed in multiple places around hackage that people add
these kinds of functions to get their JSON formatted keys (often
underscore_formatted_strings) out of Haskell's CamelCase data
properties (often withLongStringsOfCAPITALS).

I have also added to the .gitignore those files generated by the new
cabal 1.18 'sandbox' feature.

I have a few outstanding questions:

1) Should these functions live in another module with an isomorphic
inverse function, like `underscoreToCamel`? Like Aeson.Properties?
2) I am at something of a loss as to how to integrate testing into the
suite. I've tested the out at the REPL, but what steps should be
taken to integrate these into QuickCheck?

Comments (0)

Files changed (2)

 dist
+.cabal-sandbox/
+cabal.sandbox.config
 
 *.o
 *.hi
 
     , mkToJSON
     , mkParseJSON
+
+    -- * For the oft-conversion of CamelCase to underscore_case in JSON
+    , camelToUnderscore
+    , camelToUnderscoreDrop
+    , camelToUnderscoreDropChecked
     ) where
 
 --------------------------------------------------------------------------------
 -- from base:
 import Control.Applicative ( pure, (<$>), (<*>) )
 import Control.Monad       ( return, mapM, liftM2, fail )
+import Data.Char           ( isUpper, toLower)
 import Data.Bool           ( Bool(False, True), otherwise, (&&) )
 import Data.Eq             ( (==) )
 import Data.Function       ( ($), (.) )
 import Data.Int            ( Int )
 import Data.Either         ( Either(Left, Right) )
 import Data.List           ( (++), foldl, foldl', intercalate
-                           , length, map, zip, genericLength, all, partition
+                           , length, map, zip, genericLength, all, partition, drop
                            )
 import Data.Maybe          ( Maybe(Nothing, Just), catMaybes )
-import Prelude             ( String, (-), Integer, fromIntegral, error )
+import Prelude             ( String, (-), Integer, fromIntegral, error, const )
 import Text.Printf         ( printf )
 import Text.Show           ( show )
 #if __GLASGOW_HASKELL__ < 700
 valueConName (Number _) = "Number"
 valueConName (Bool   _) = "Boolean"
 valueConName Null       = "Null"
+
+-- | Removes the first Int characters of string, then converts from
+--   CamelCase to underscore_case.
+--
+--   For use by Aeson template haskell calls.
+camelToUnderscore :: String -> String
+camelToUnderscore = camelToUnderscoreDrop 0
+
+-- | Removes the first Int characters of string, then converts from
+--   CamelCase to underscore_case. Drops the first few characters from
+--   the input.
+--
+--   For use by Aeson template haskell calls.
+camelToUnderscoreDrop :: Int -> String -> String
+camelToUnderscoreDrop i = camelToUnderscoreDropChecked (const i)
+
+-- | Removes the first Int characters of string, then converts from
+--   CamelCase to underscore_case. Investigates the input string to
+--   see how many characters to drop.
+--
+--   For use by Aeson template haskell calls.
+camelToUnderscoreDropChecked :: (String -> Int) -> String -> String
+camelToUnderscoreDropChecked chk property =
+    underscore True input
+  where
+    input :: String
+    input = drop (chk property) property
+
+    underscore :: Bool    -- ^ Previous was a capital letter
+               -> String  -- ^ The remaining string
+               -> String
+    underscore _    []           = []
+    underscore prev (x : xs)     = if isUpper x
+                                      then if prev
+                                             then toLower x : underscore True xs
+                                             else '_' : toLower x : underscore True xs
+                                      else x : underscore False xs
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.