module Desktop.Portal.Util ( optionalFromVariant, mapJust, toVariantPair, toVariantPair', encodeNullTerminatedUtf8, ) where import DBus (IsVariant, Variant) import DBus qualified import Data.Binary.Builder qualified as Binary import Data.ByteString.Lazy (ByteString) import Data.Map (Map) import Data.Map qualified as Map import Data.Text (Text) import Data.Text.Encoding qualified as Encoding -- | Returns @Just Nothing@ if the field does not exist, @Just (Just x)@ if it does exist and -- can be turned into the expected type, or @Nothing@ if the field exists with the wrong type. optionalFromVariant :: forall a. IsVariant a => Text -> Map Text Variant -> Maybe (Maybe a) optionalFromVariant key variants = mapJust DBus.fromVariant (Map.lookup key variants) mapJust :: (a -> Maybe b) -> Maybe a -> Maybe (Maybe b) mapJust f = \case Nothing -> Just Nothing Just x -> Just <$> f x toVariantPair :: IsVariant a => Text -> Maybe a -> Maybe (Text, Variant) toVariantPair = toVariantPair' id toVariantPair' :: IsVariant b => (a -> b) -> Text -> Maybe a -> Maybe (Text, Variant) toVariantPair' f key = \case Nothing -> Nothing Just x -> Just (key, DBus.toVariant (f x)) encodeNullTerminatedUtf8 :: Text -> ByteString encodeNullTerminatedUtf8 txt = Binary.toLazyByteString (Encoding.encodeUtf8Builder txt <> Binary.singleton 0)