2015-03-30 1 views
1

je le code suivant (qui est censé analyser un très trivial hachage { "url": "http://some.url.here/" }):Éviter chaîne aller-retour dans Aeson

import   Control.Applicative 
import qualified Data.ByteString  as B 
import   Data.ByteString.Char8 (pack) 


import   Data.Aeson   () 
import   Data.Aeson.Types 



newtype SetNextUrl = SetNextUrl B.ByteString 

instance FromJSON SetNextUrl where 
    parseJSON (Object v) = SetNextUrl <$> 
     (pack <$> v .: "url") 

Remarquez maintenant que je laissant entendre que « url » est de type String en utilisant pack ... Cela va bien sûr entraîner des frais généraux de conversion: de l'entrée ByteString à un [Char] et retour ....

Question: Comment puis-je demander à Aeson d'interpréter le champ "url" comme ByteString?

Répondre

4

aeson utilise Text en interne pour les valeurs de chaîne, donc si vous utilisez Data.Text.Encoding.encodeUtf8 vous n'aurez pas la conversion Text -> String -> ByteString, il va juste aller directement à partir Text -> ByteString (ce qui est assez IIRC pas cher)

+0

Merci! J'aurais probablement dû utiliser Text dans plus d'endroits et ByteString dans moins ... Mais votre solution est géniale! – dsign

+0

@dsign Vous devriez utiliser celui qui convient le mieux à votre application. Si vous manipulez des octets réels, utilisez ByteString, c'est son travail. C'est essentiellement un 'Vector Word8' sous le capot. Si vous travaillez avec des données ASCII uniquement, alors c'est approprié. Si vous travaillez avec du texte lisible/inscriptible par un humain, utilisez Texte. Il gère toutes les parties dures de l'encodage pour vous. Si vous voulez mettre ByteStrings dans un fichier JSON, vous devriez peut-être regarder [BSON] (http://bsonspec.org/) à la place. – bheklilr

+0

@bheklilr C'est un très bon point et la raison pour laquelle j'ai écrit mon commentaire ... J'ai utilisé ByteStrings ala Python 2.x str: pour unicode et octets .... Certaines de ces utilisations devraient plutôt être des textes. – dsign