我正在尝试将Base64编码为JSON。我遇到了this对话。我注意到snoyberg已经将Base64
newtype
包含在FP完整代码库中,所以我想我会尝试一下。
将限定的Data.ByteString导入为B
将限定的Data.ByteString.Base64导入为B64
newtype Base64 = Base64 {toByteString :: B.ByteString}
派生(Eq,Ord,Show,IsString)
ToJSON
实例似乎很简单。我很感激理智。
实例ToJSON Base64在哪里 toJSON(Base64 bs)=
toJSON $ B.unpack $ B64.decodeLenient bs
FromJSON实例是我遇到问题的地方。
研究其他我猜测的例子我必须使用想要withArray
的{{1}}。这就是我被卡住的地方。
parseBase64 :: Array - >解析器
parseBase64(Array a)= ...
我在这里尝试了很多方法,我很困惑这里需要发生什么,或者即使我在正确的轨道上也是如此。如果我能得到一些简单的反馈,如“你在正确的轨道上继续前进”,或指向不同的方向,那将是值得赞赏的。
答案 0 :(得分:2)
-- | Get base64 encoded bytestring
getEncodedByteString64 :: ByteString64 -> ByteString
getEncodedByteString64 = Base64.encode . getByteString64
instance ToJSON ByteString64 where
toJSON = toJSON . decodeLatin1 . getEncodedByteString64
instance FromJSON ByteString64 where
parseJSON = withText "ByteString" $
pure . ByteString64 . decodeLenient . encodeUtf8
仔细观察后,似乎您将ByteString
(任意)编码为' Word8'(这是BS.unpack
返回的)数组,您可以执行此操作,并且Base64
中的编码字节字符串:
instance ToJSON Base64 where
toJSON = toJSON . B.unpack . B64.decodeLenient . toByteString
instance FromJSON Base64 where
parseJSON = fmap (Base64 . B64.encode . B.pack) . parseJSON
这样,您就不必担心[Word8]
的编码方式,只要它按照解码方式进行解码。
如果您想手动处理数组,那么它将如下所示:
instance FromJSON Base64 where
parseJSON (Array a) = do
a' <- traverse parseJSON a -- :: Parser (V.Vector Word8)
return $ Base64 . B64.encode . B.pack . V.toList $ a'
parseJSON _ = fail "Array expected"
或
instance FromJSON Base64 where
parseJSON = withArray "Base64" $ \a -> do
a' <- traverse parseJSON a -- :: Parser (V.Vector Word8)
return $ Base64 . B64.encode . B.pack . V.toList $ a'