You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a Haskell field like addressLine1 and I use snakeCase to convert that to snake case for the aeson representation. The parser expects a field named address_line1, but the API returns address_line_1.
It would obviously be bad for a field like foo1234 to show up as foo_1_2_3_4, but I would expect it to render as foo_1234. I don't think that's unambiguously correct, though - expecting it to output foo1234 also seems reasonable to me.
Another case is fooID or someHTTPConfig - these get rendered as foo_i_d and some_h_t_t_p_config. This is probably not desired - I'd expect foo_id and some_http_config as the output of those functions.
I wrote some rather tricky code that handles these cases correctly for work. Specifically, we wanted to render an enum-like sum type with spaces in between the words, but it'd be easy to port this to make it do snake_caseing:
--| Used for converting an enum with a derived 'Show' instance into a title-- case. Drops the type name prefix if present.---- This function will produce weird results on interesting sum types - it's best-- to only use it on boring enum-like types.constructorToTitleWords::foralla. (Typeablea, Showa) =>a->String
constructorToTitleWords constr =
insertSpaces
$ fromMaybe constrStr
$List.stripPrefix (show (typeOf constr))
$ constrStr
where
constrStr =show constr
insertSpaces []=[]
insertSpaces chars =let
withNext =
withLastAndNext chars
insertSpace =concatMap$\(mp, c, mn) ->if isUpperM mp &&C.isUpper c && isUpperM mn
then [c]
elseif isUpperM mp &&C.isLower c && isLowerM mn
then [c]
elseif isUpperM mp &&C.isUpper c && isLowerM mn
then ['', c]
elseif isJust mp &&C.isUpper c && isLowerM mn
then ['', c]
elseif isLowerM mp &&C.isUpper c
then ['', c]
elseifnot (isDigitM mp) &&C.isDigit c
then ['', c]
else [c]
isLowerM =maybeFalseC.isLower
isUpperM =maybeFalseC.isUpper
isDigitM =maybeFalseC.isDigit
in
insertSpace withNext
withLastAndNext:: [a] -> [(Maybea, a, Maybea)]
withLastAndNext xs =
mkSuccession (Nothing:fmapJust xs) xs (Just<$>drop1 xs)
where
mkSuccession (cp : cps) (cc : ccs) (cn : cns) =
(cp, cc, cn) : mkSuccession cps ccs cns
mkSuccession (cp : cps) (cc : ccs) []=
(cp, cc, Nothing) : mkSuccession cps ccs []
mkSuccession _ [] _ =[]
mkSuccession _ _ _ =error$"mkSuccession internal invariant failed: lists did not have the "<>"right lengths."-- tests:dataConstructorToTitleWordsTest=NoTypePrefix
| ConstructorToTitleWordsTestWithTypePrefix
| WithAcronymHTTPHooray
| IAmSorryForThisEdgeCase
| TwoAcronymEdgeCaseHTTPFTP
| OhManNumbers1234deriving (Show, Read, Eq)
spec::Spec
spec =do
describe "constructorToTitleWords"$do
it "works"$do
constructorToTitleWords NoTypePrefix`shouldBe`"No Type Prefix"
it "strips type prefix"$do
constructorToTitleWords ConstructorToTitleWordsTestWithTypePrefix`shouldBe`"With Type Prefix"
it "doesn't bork acronyms"$do
constructorToTitleWords WithAcronymHTTPHooray`shouldBe`"With Acronym HTTP Hooray"
it "does not handle single letter words"$do
constructorToTitleWords IAmSorryForThisEdgeCase`shouldBe`"I Am Sorry For This Edge Case"
it "does not handle two adjacent acronyms"$do
constructorToTitleWords TwoAcronymEdgeCaseHTTPFTP`shouldBe`"Two Acronym Edge Case HTTPFTP"
it "works with numbers"$do
constructorToTitleWords OhManNumbers1234`shouldBe`"Oh Man Numbers 1234"
The text was updated successfully, but these errors were encountered:
I have a Haskell field like
addressLine1
and I usesnakeCase
to convert that to snake case for the aeson representation. The parser expects a field namedaddress_line1
, but the API returnsaddress_line_1
.It would obviously be bad for a field like
foo1234
to show up asfoo_1_2_3_4
, but I would expect it to render asfoo_1234
. I don't think that's unambiguously correct, though - expecting it to outputfoo1234
also seems reasonable to me.Another case is
fooID
orsomeHTTPConfig
- these get rendered asfoo_i_d
andsome_h_t_t_p_config
. This is probably not desired - I'd expectfoo_id
andsome_http_config
as the output of those functions.I wrote some rather tricky code that handles these cases correctly for work. Specifically, we wanted to render an enum-like sum type with spaces in between the words, but it'd be easy to port this to make it do
snake_case
ing:The text was updated successfully, but these errors were encountered: