Selective instance is always running the patching parser
I was hoping to be able to avoid unneeded parsing using select but it's not the case. My specific case is avoiding to require a passphrase in the env vars if the secret is not encrypted. I can work around with a default dummy value for the passphrase, but that looks like a hack.
Is there a fundamental limitation that prevents select to avoid the patching parser to execute when the primary parser gives a Right ?
Pasting the code of my example.
```haskell
import Data.Aeson qualified as Aeson
import Data.ByteString.Lazy qualified as BL
import Data.Text (Text)
import OptEnvConf
( Alternative ((<|>))
, Parser
, Selective (select)
, checkMapIO
, conf
, env
, help
, metavar
, reader
, setting
, str
, withConfig
)
data MnemonicsPhase = UndecryptablePhase | DecryptablePhase
deriving (Show, Eq)
data Mnemonics a where
ClearText :: Text -> Mnemonics a
Encrypted :: Text -> Mnemonics UndecryptablePhase
Decryptable :: Text -> Text -> Mnemonics DecryptablePhase
instance FromJSON (Mnemonics UndecryptablePhase) where
parseJSON = withObject "Mnemonics" $ \v -> do
ClearText <$> v .: "mnemonics"
<|> Encrypted <$> v .: "encryptedMnemonics"
instance ToJSON (Mnemonics DecryptablePhase) where
toJSON (ClearText mnemonics) =
object ["mnemonics" .= mnemonics]
toJSON (Decryptable mnemonics _) =
object ["encryptedMnemonics" .= mnemonics]
eitherMnemonics
:: Mnemonics UndecryptablePhase
-> Either Text (Mnemonics DecryptablePhase)
eitherMnemonics (ClearText mnemonics) = Right $ ClearText mnemonics
eitherMnemonics (Encrypted mnemonics) = Left mnemonics
mnemonicsClearTextOption :: Parser Text
mnemonicsClearTextOption =
setting
[ help "The mnemonics for the wallet in clear text"
, conf "mnemonics"
, metavar "MNEMONICS"
]
mnemonicsEncryptedOption :: Parser Text
mnemonicsEncryptedOption =
setting
[ help "The encrypted mnemonics for the wallet"
, conf "encryptedMnemonics"
, metavar "ENCRYPTED_MNEMONICS"
]
walletPassphraseOption
:: Parser (Text -> Mnemonics DecryptablePhase)
walletPassphraseOption =
flip Decryptable
<$> setting
[ env "ANTI_WALLET_PASSPHRASE"
, metavar "PASSPHRASE"
, help "The passphrase for the encrypted mnemonics"
, reader str
]
walletFileOption :: Parser FilePath
walletFileOption =
setting
[ env "ANTI_WALLET_FILE"
, metavar "FILEPATH"
, help "The file path to the wallet secrets"
, reader str
]
undecryptableMnemonicsParser :: Parser (Mnemonics UndecryptablePhase)
undecryptableMnemonicsParser =
ClearText <$> mnemonicsClearTextOption
<|> Encrypted <$> mnemonicsEncryptedOption
mnemonicsObject :: Parser Object
mnemonicsObject =
checkMapIO
(fmap Aeson.eitherDecode . BL.readFile)
walletFileOption
mnemonicsParser :: Parser (Mnemonics DecryptablePhase)
mnemonicsParser =
withConfig (Just <$> mnemonicsObject)
$ select
(eitherMnemonics <$> undecryptableMnemonicsParser)
walletPassphraseOption
```
In case the `ANTI_WALLET_FILE` content is
```json
{ "mnemonics": "abc" }
```
I am not expecting the `ANTI_WALLET_PASSPHRASE` to be required, but it is.
Thanks for this library BTW ;-) .
2 条评论