on master help sign in
Rename new camelTo to camelTo2

Also add test-cases for it.

commitd4132fbb623c8269c7b7072edeb1bd942ec69718 authorKostiantyn Rybnikov <k-bx@k-bx.com> dateMon 13 Jul 2015, 17:39 (11 years ago) parentc43f9b0
3 files changed+32−5
Data/Aeson/Types.hs+1 Data/Aeson/Types/Internal.hs+18−2 tests/UnitTests.hs+13−3
Data/Aeson/Types.hs+1
@@ -62,6 +62,7 @@ module Data.Aeson.Types
6262 , Options(..)
6363 , SumEncoding(..)
6464 , camelTo
65+ , camelTo2
6566 , defaultOptions
6667 , defaultTaggedObject
6768 ) where
Data/Aeson/Types/Internal.hs+18−2
@@ -47,6 +47,7 @@ module Data.Aeson.Types.Internal
4747
4848 -- * Used for changing CamelCase names into something else.
4949 , camelTo
50+ , camelTo2
5051
5152 -- * Other types
5253 , DotNetTime(..)
@@ -519,9 +520,24 @@ defaultTaggedObject = TaggedObject
519520-- For use by Aeson template haskell calls.
520521--
521522-- > camelTo '_' 'CamelCaseAPI' == "camel_case_api"
522−-- > camelTo '_' 'CamelAPICase' == "camel_api_case"
523523camelTo :: Char -> String -> String
524−camelTo c = map toLower . go2 . go1
524+camelTo c = lastWasCap True
525+ where
526+ lastWasCap :: Bool -- ^ Previous was a capital letter
527+ -> String -- ^ The remaining string
528+ -> String
529+ lastWasCap _ [] = []
530+ lastWasCap prev (x : xs) = if isUpper x
531+ then if prev
532+ then toLower x : lastWasCap True xs
533+ else c : toLower x : lastWasCap True xs
534+ else x : lastWasCap False xs
535+
536+-- | Better version of 'camelTo'. Example where it works better:
537+--
538+-- > camelTo2 '_' 'CamelAPICase' == "camel_api_case"
539+camelTo2 :: Char -> String -> String
540+camelTo2 c = map toLower . go2 . go1
525541 where go1 "" = ""
526542 go1 (x:u:l:xs) | isUpper u && isLower l = x : c : u : l : go1 xs
527543 go1 (x:xs) = x : go1 xs
tests/UnitTests.hs+13−3
@@ -5,7 +5,7 @@ module UnitTests (ioTests, tests) where
55import Control.Monad (forM)
66import Data.Aeson (eitherDecode, encode, genericToJSON, genericToEncoding)
77import Data.Aeson.Encode (encodeToTextBuilder)
8−import Data.Aeson.Types (ToJSON(..), Value, camelTo, defaultOptions)
8+import Data.Aeson.Types (ToJSON(..), Value, camelTo, camelTo2, defaultOptions)
99import Data.Char (toUpper)
1010import GHC.Generics (Generic)
1111import Test.Framework (Test, testGroup)
@@ -21,6 +21,13 @@ tests = testGroup "unit" [
2121 testCase "camelTo" $ roundTripCamel "aName"
2222 , testCase "camelTo" $ roundTripCamel "another"
2323 , testCase "camelTo" $ roundTripCamel "someOtherName"
24+ , testCase "camelTo" $
25+ assertEqual "" "camel_apicase" (camelTo '_' "CamelAPICase")
26+ , testCase "camelTo2" $ roundTripCamel2 "aName"
27+ , testCase "camelTo2" $ roundTripCamel2 "another"
28+ , testCase "camelTo2" $ roundTripCamel2 "someOtherName"
29+ , testCase "camelTo2" $
30+ assertEqual "" "camel_api_case" (camelTo2 '_' "CamelAPICase")
2431 ]
2532 , testGroup "encoding" [
2633 testCase "goodProducer" $ goodProducer
@@ -30,10 +37,13 @@ tests = testGroup "unit" [
3037roundTripCamel :: String -> Assertion
3138roundTripCamel name = assertEqual "" name (camelFrom '_' $ camelTo '_' name)
3239
40+roundTripCamel2 :: String -> Assertion
41+roundTripCamel2 name = assertEqual "" name (camelFrom '_' $ camelTo2 '_' name)
3342
43+camelFrom :: Char -> String -> String
44+camelFrom c s = let (p:ps) = split c s
45+ in concat $ p : map capitalize ps
3446 where
35− camelFrom c s = let (p:ps) = split c s
36− in concat $ p : map capitalize ps
3747 split c s = map L.unpack $ L.split c $ L.pack s
3848 capitalize t = toUpper (head t) : tail t
3949