-
-
Notifications
You must be signed in to change notification settings - Fork 39
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
Generic codec: Don't silently succeed when decoding encounters invalid types #223
Comments
Hi @TomMD! Your proposed implementation of It turned out that the previous implementation didn't work as expected in our project. This implementation led to an unexpected bug which was hard to find and spot due to the ad-hoc nature of this function. Current The problem with our previous version was that it compared expected and given keys to return The problem with your solution is that you return So I can see how a codec that returns |
Hi all, I ended up here after If I understand, Any thoughts about better solutions, or ways to improve these? Thanks! import Toml.Codec.BiMap (BiMap (..), TomlBiMap)
import Toml.Codec.Types (Codec(..), TomlCodec, TomlEnv, TomlState(..), eitherToTomlState)
import Toml.Type.AnyValue (AnyValue (..))
import Toml.Type.Key (Key)
import Toml.Type.TOML (TOML(..), insertKeyAnyVal, insertTable)
import Toml.Codec.Combinator.Common (whenLeftBiMapError)
import Toml.Codec.Combinator.Table (handleTableErrors)
import qualified Toml.Type.PrefixTree as Prefix
import qualified Data.HashMap.Strict as HashMap
-- based on match from Toml.Codec.Combinator.Common
matchMaybe :: forall a. TomlBiMap a AnyValue -> Key -> TomlCodec (Maybe a)
matchMaybe BiMap{..} key = Codec input output
where
input :: TomlEnv (Maybe a)
input = \toml -> case HashMap.lookup key (tomlPairs toml) of
Nothing -> pure Nothing
Just anyVal -> whenLeftBiMapError key (backward anyVal) (pure . pure)
output :: Maybe a -> TomlState (Maybe a)
output Nothing = pure Nothing
output (Just a) = do
anyVal <- eitherToTomlState $ forward a
(Just a) <$ modify (insertKeyAnyVal key anyVal)
-- based on match from Toml.Codec.Combinator.Common
matchEmpty :: forall a. Monoid a => TomlBiMap a AnyValue -> Key -> TomlCodec a
matchEmpty BiMap{..} key = Codec input output
where
input :: TomlEnv a
input = \toml -> case HashMap.lookup key (tomlPairs toml) of
Nothing -> pure mempty
Just anyVal -> whenLeftBiMapError key (backward anyVal) pure
output :: a -> TomlState a
output a = do
anyVal <- eitherToTomlState $ forward a
a <$ modify (insertKeyAnyVal key anyVal)
-- based on table from Toml.Codec.Combinator.Table
tableMaybe :: forall a. TomlCodec a -> Key -> TomlCodec (Maybe a)
tableMaybe codec key = Codec input output
where
input :: TomlEnv (Maybe a)
input = \t -> case Prefix.lookup key $ tomlTables t of
Nothing -> pure Nothing
Just toml -> pure <$> handleTableErrors codec key toml
output :: Maybe a -> TomlState (Maybe a)
output Nothing = pure Nothing
output (Just a) = do
mTable <- gets $ Prefix.lookup key . tomlTables
let toml = fromMaybe mempty mTable
let (_, newToml) = unTomlState (codecWrite codec a) toml
(Just a) <$ modify (insertTable key newToml) |
Small ask: Can we get semioptional added to the Bi monad module? I want a Codec for
Maybe a
to fail if the types do not match. Happy to make the PR if this is ok to you.Bigger ask: Can we use
semioptional
instead ofdioptional
for the genericCodec? Also happy to make this PR.The text was updated successfully, but these errors were encountered: