Commits

Bryan O'Sullivan committed da55314 Merge

Merge pull request #155 from gabemc/master

Adding functions to TH to make CamelCase to under_score easier.

Comments (0)

Files changed (4)

 dist
+.cabal-sandbox/
+cabal.sandbox.config
 
 *.o
 *.hi
 
 tests/qc
 
-cabal.sandbox.config
+cabal.sandbox.config

Data/Aeson/TH.hs

File contents unchanged.

Data/Aeson/Types/Internal.hs

     , defaultOptions
     , defaultTaggedObject
 
+    -- * Used for changing CamelCase names into something else.
+    , camelTo
+
     -- * Other types
     , DotNetTime(..)
     ) where
 
+
 import Control.Applicative
 import Control.Monad
 import Control.DeepSeq (NFData(..))
+import Data.Char (toLower, isUpper)
 import Data.Scientific (Scientific)
 import Data.Hashable (Hashable(..))
 import Data.Data (Data)
                       { tagFieldName      = "tag"
                       , contentsFieldName = "contents"
                       }
+
+-- | Converts from CamelCase to another lower case, interspersing
+--   the character between all capital letters and their previous
+--   entries, except those capital letters that appear together,
+--   like 'API'.
+--
+--   For use by Aeson template haskell calls.
+--
+--   > camelTo '_' 'CamelCaseAPI' == "camel_case_api"
+camelTo :: Char -> String -> String
+camelTo c = lastWasCap True
+  where
+    lastWasCap :: Bool    -- ^ Previous was a capital letter
+              -> String  -- ^ The remaining string
+              -> String
+    lastWasCap _    []           = []
+    lastWasCap prev (x : xs)     = if isUpper x
+                                      then if prev
+                                             then toLower x : lastWasCap True xs
+                                             else c : toLower x : lastWasCap True xs
+                                      else x : lastWasCap False xs
+

tests/Properties.hs

 import qualified Data.Map as Map
 #endif
 
+roundTripCaml :: String -> Bool
+roundTripCaml s = s == (camlFrom '_' $ camlTo '_' s)
+  where
+    camlFrom :: Char -> String -> String
+    camlFrom c = concatMap capitalize $ split c
 
 encodeDouble :: Double -> Double -> Bool
 encodeDouble num denom
       testProperty "encodeDouble" encodeDouble
     , testProperty "encodeInteger" encodeInteger
     ],
+  testGroup "camlCase" [
+      testProperty "camlTo" $ roundTripCaml "AnApiMethod"
+    , testProperty "camlTo" $ roundTripCaml "anotherMethodType"
+    ],
   testGroup "roundTrip" [
       testProperty "Bool" $ roundTripEq True
     , testProperty "Double" $ roundTripEq (1 :: Approx Double)