% Copyright (C) 2009 John Millikin % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \ignore{ \begin{code} {-# LANGUAGE DeriveDataTypeable #-} module DBus.Types.Containers.Dictionary ( Dictionary , toDictionary , fromDictionary , dictionaryItems , dictionaryFromItems , dictionarySignature ) where import Control.Arrow ((***)) import Data.Typeable (Typeable, cast) import qualified DBus.Types.Signature as S import qualified DBus.Types.Atom as A import qualified DBus.Types.Containers.Variant as V \end{code} } \subsubsection{Dictionaries} Dictionaries are a key $\rightarrow$ value mapping, where the keys must be of an {\tt Atomic} type, and the values may be of any valid DBus type. \begin{code} data Dictionary = Dictionary S.Signature [(A.Atom, V.Variant)] deriving (Show, Eq, Typeable) \end{code} \begin{code} instance V.Variable Dictionary where defaultSignature _ = S.mkSignature' "a{yy}" toVariant x = V.Variant (dictionarySignature x) x fromVariant (V.Variant _ x) = cast x \end{code} \begin{code} toDictionary :: (A.Atomic a, V.Variable b) => [(a, b)] -> Maybe Dictionary toDictionary pairs = dictionaryFromItems kSig vSig pairs' where fakePair = head $ (undefined, undefined) : pairs kSigFake = V.defaultSignature . fst $ fakePair vSigFake = V.defaultSignature . snd $ fakePair pairs' = map (A.toAtom *** V.toVariant) pairs kSigReal = A.atomSignature . fst . head $ pairs' vSigReal = V.variantSignature . snd . head $ pairs' (kSig, vSig) = case pairs of [] -> (kSigFake, vSigFake) _ -> (kSigReal, vSigReal) \end{code} \begin{code} dictionaryFromItems :: S.Signature -> S.Signature -> [(A.Atom, V.Variant)] -> Maybe Dictionary dictionaryFromItems kSig vSig pairs = maybeDict where maybeDict = if hasSignature kSig ks && hasSignature vSig vs then Just (Dictionary sig pairs) else Nothing ks = map (A.atomToVariant . fst) pairs vs = map snd pairs kSig' = S.strSignature kSig vSig' = S.strSignature vSig sig = S.mkSignature' $ "a{" ++ kSig' ++ vSig' ++ "}" \end{code} \begin{code} fromDictionary :: (A.Atomic a, V.Variable b) => Dictionary -> Maybe [(a, b)] fromDictionary (Dictionary _ vs) = mapM fromVariant' vs where fromVariant' (k, v) = do k' <- A.fromAtom k v' <- V.fromVariant v return (k', v') \end{code} \begin{code} dictionaryItems :: Dictionary -> [(A.Atom, V.Variant)] dictionaryItems (Dictionary _ vs) = vs \end{code} \begin{code} dictionarySignature :: Dictionary -> S.Signature dictionarySignature (Dictionary s _) = s \end{code} \subsubsection*{Helper functions} \begin{code} hasSignature :: S.Signature -> [V.Variant] -> Bool hasSignature _ [] = True hasSignature sig vs = all (== sig) . map V.variantSignature $ vs \end{code}