provide a way to extract/print the names of environment variables used?
phlummox opened this issue · 0 comments
phlummox commented
It'd be nice to be able to quickly produce a list of generated environment variable names being used, when one makes an instance of FromEnv
for a type that has a Generics
instance. That way, the list can be included in documentation.
The following code provides a method extract
to do this:
class Extract a where
extract :: a -> [String]
default extract :: (GExtract (Rep a), Generic a) => a -> [String]
extract x = gExtract (from x) defOption
class GExtract f where
gExtract :: f a -> Option -> [String]
instance (GExtract a, GExtract b) => GExtract (a :*: b) where
gExtract (a :*: b) opts = gExtract a opts <> gExtract b opts
instance GExtract a => GExtract (C1 i a) where
gExtract (M1 x) = gExtract x
instance GExtract a => GExtract (D1 i a) where
gExtract (M1 x) = gExtract x
instance (Selector s, Var a) => GExtract (S1 s (K1 i a)) where
gExtract m@(M1 (K1 def)) opts = [toEnvName opts $ selName m]
where `selName` and `snake` are split out into top level functions to avoid duplication (expand for details).
toEnvName :: Option -> String -> String
toEnvName Option{..} xs =
let name = snake (drop dropPrefixCount xs)
in if customPrefix == mempty
then name
else map toUpper customPrefix ++ "_" ++ name
snake :: String -> String
snake = map toUpper . snakeCase
where
applyFirst :: (Char -> Char) -> String -> String
applyFirst _ [] = []
applyFirst f [x] = [f x]
applyFirst f (x:xs) = f x: xs
snakeCase :: String -> String
snakeCase = u . applyFirst toLower
where u [] = []
u (x:xs) | isUpper x = '_' : toLower x : snakeCase xs
| otherwise = x : u xs
Is this a feature that could be added to Envy?