on master help sign in
Merge
238654fBryan O'Sullivan
Data/Aeson/Types.hs+1
@@ -62,6 +62,7 @@ module Data.Aeson.Types
62 , Options(..)
62 , Options(..)
63 , SumEncoding(..)
63 , SumEncoding(..)
64 , camelTo
64 , camelTo
65+ , camelTo2
65 , defaultOptions
66 , defaultOptions
66 , defaultTaggedObject
67 , defaultTaggedObject
67 ) where
68 ) where
Data/Aeson/Types/Internal.hs+15−1
@@ -47,6 +47,7 @@ module Data.Aeson.Types.Internal
47
47
48 -- * Used for changing CamelCase names into something else.
48 -- * Used for changing CamelCase names into something else.
49 , camelTo
49 , camelTo
50+ , camelTo2
50
51
51 -- * Other types
52 -- * Other types
52 , DotNetTime(..)
53 , DotNetTime(..)
@@ -56,7 +57,7 @@ import Control.Applicative
56import Control.Monad
57import Control.Monad
57import Control.DeepSeq (NFData(..))
58import Control.DeepSeq (NFData(..))
58import Data.ByteString.Builder (Builder, char7, toLazyByteString)
59import Data.ByteString.Builder (Builder, char7, toLazyByteString)
59−import Data.Char (toLower, isUpper)
60+import Data.Char (toLower, isUpper, isLower)
60import Data.Scientific (Scientific)
61import Data.Scientific (Scientific)
61import Data.Foldable (Foldable(..))
62import Data.Foldable (Foldable(..))
62import Data.Hashable (Hashable(..))
63import Data.Hashable (Hashable(..))
@@ -561,3 +562,16 @@ camelTo c = lastWasCap True
561 then toLower x : lastWasCap True xs
562 then toLower x : lastWasCap True xs
562 else c : toLower x : lastWasCap True xs
563 else c : toLower x : lastWasCap True xs
563 else x : lastWasCap False xs
564 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
5import Control.Monad (forM)
5import Control.Monad (forM)
6import Data.Aeson (eitherDecode, encode, genericToJSON, genericToEncoding)
6import Data.Aeson (eitherDecode, encode, genericToJSON, genericToEncoding)
7import Data.Aeson.Encode (encodeToTextBuilder)
7import Data.Aeson.Encode (encodeToTextBuilder)
8−import Data.Aeson.Types (ToJSON(..), Value, camelTo, defaultOptions)
8+import Data.Aeson.Types (ToJSON(..), Value, camelTo, camelTo2, defaultOptions)
9import Data.Char (toUpper)
9import Data.Char (toUpper)
10import GHC.Generics (Generic)
10import GHC.Generics (Generic)
11import Test.Framework (Test, testGroup)
11import Test.Framework (Test, testGroup)
@@ -21,6 +21,13 @@ tests = testGroup "unit" [
21 testCase "camelTo" $ roundTripCamel "aName"
21 testCase "camelTo" $ roundTripCamel "aName"
22 , testCase "camelTo" $ roundTripCamel "another"
22 , testCase "camelTo" $ roundTripCamel "another"
23 , testCase "camelTo" $ roundTripCamel "someOtherName"
23 , 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")
24 ]
31 ]
25 , testGroup "encoding" [
32 , testGroup "encoding" [
26 testCase "goodProducer" $ goodProducer
33 testCase "goodProducer" $ goodProducer
@@ -30,10 +37,13 @@ tests = testGroup "unit" [
30roundTripCamel :: String -> Assertion
37roundTripCamel :: String -> Assertion
31roundTripCamel name = assertEqual "" name (camelFrom '_' $ camelTo '_' name)
38roundTripCamel name = assertEqual "" name (camelFrom '_' $ camelTo '_' name)
32
39
40+roundTripCamel2 :: String -> Assertion
41+roundTripCamel2 name = assertEqual "" name (camelFrom '_' $ camelTo2 '_' name)
33
42
43+camelFrom :: Char -> String -> String
44+camelFrom c s = let (p:ps) = split c s
45+ in concat $ p : map capitalize ps
34 where
46 where
35− camelFrom c s = let (p:ps) = split c s
36− in concat $ p : map capitalize ps
37 split c s = map L.unpack $ L.split c $ L.pack s
47 split c s = map L.unpack $ L.split c $ L.pack s
38 capitalize t = toUpper (head t) : tail t
48 capitalize t = toUpper (head t) : tail t
39
49