on master help sign in
Merge
commit238654f25ed2007acf40d9f70e673f6bb3ceb88f authorBryan O'Sullivan <bos@serpentine.com> dateMon 13 Jul 2015, 09:52 (11 years ago) parent360d5113c5a1f1
3 files changed+29−4
Data/Aeson/Types.hs+1 Data/Aeson/Types/Internal.hs+15−1 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+15−1
@@ -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(..)
@@ -56,7 +57,7 @@ import Control.Applicative
5657import Control.Monad
5758import Control.DeepSeq (NFData(..))
5859import Data.ByteString.Builder (Builder, char7, toLazyByteString)
59−import Data.Char (toLower, isUpper)
60+import Data.Char (toLower, isUpper, isLower)
6061import Data.Scientific (Scientific)
6162import Data.Foldable (Foldable(..))
6263import Data.Hashable (Hashable(..))
@@ -561,3 +562,16 @@ camelTo c = lastWasCap True
561562 then toLower x : lastWasCap True xs
562563 else c : toLower x : lastWasCap True xs
563564 else x : lastWasCap False xs
565+
566+-- | Better version of 'camelTo'. Example where it works better:
567+--
568+-- > camelTo '_' 'CamelAPICase' == "camel_apicase"
569+-- > camelTo2 '_' 'CamelAPICase' == "camel_api_case"
570+camelTo2 :: Char -> String -> String
571+camelTo2 c = map toLower . go2 . go1
572+ where go1 "" = ""
573+ go1 (x:u:l:xs) | isUpper u && isLower l = x : c : u : l : go1 xs
574+ go1 (x:xs) = x : go1 xs
575+ go2 "" = ""
576+ go2 (l:u:xs) | isLower l && isUpper u = l : c : u : go2 xs
577+ go2 (x:xs) = x : go2 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