Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

provide a way to extract/print the names of environment variables used? #40

Open
phlummox opened this issue Nov 24, 2020 · 0 comments
Open

Comments

@phlummox
Copy link

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant