mirror of
https://github.com/byteverse/colonnade.git
synced 2026-01-23 12:41:58 +01:00
87 lines
2.9 KiB
Haskell
87 lines
2.9 KiB
Haskell
module Main (main) where
|
|
|
|
import Test.QuickCheck (Gen, Arbitrary(..), choose)
|
|
import Test.Framework (defaultMain, testGroup, Test)
|
|
import Test.Framework.Providers.QuickCheck2 (testProperty)
|
|
import Data.ByteString (ByteString)
|
|
import Data.Either.Combinators
|
|
import Colonnade.Types
|
|
import Data.Functor.Contravariant (contramap)
|
|
import Data.Functor.Contravariant.Divisible (divided,conquered)
|
|
import qualified Data.ByteString.Builder as Builder
|
|
import qualified Data.ByteString.Lazy as LByteString
|
|
import qualified Data.ByteString as ByteString
|
|
import qualified Data.ByteString.Char8 as BC8
|
|
import qualified Colonnade.Decoding as Decoding
|
|
import qualified Colonnade.Encoding as Encoding
|
|
|
|
main :: IO ()
|
|
main = defaultMain tests
|
|
|
|
tests :: [Test]
|
|
tests = []
|
|
[ testGroup "ByteString encode/decode"
|
|
[ testProperty "Headless Isomorphism (int,char,bool)"
|
|
$ propEncodeDecodeIso
|
|
(ipv4ToTextNaive)
|
|
(ipv4FromTextNaive)
|
|
]
|
|
]
|
|
|
|
|
|
byteStringDecodeInt :: ByteString -> Either String Int
|
|
byteStringDecodeInt b = do
|
|
(a,bsRem) <- maybe (Left "could not parse int") Right (BC8.readInt b)
|
|
if ByteString.null bsRem
|
|
then Right a
|
|
else Left "found extra characters after int"
|
|
|
|
byteStringDecodeChar :: ByteString -> Either String Char
|
|
byteStringDecodeChar b = case BC8.length b of
|
|
1 -> Right (BC8.head b)
|
|
0 -> Left "cannot decode Char from empty bytestring"
|
|
_ -> Left "cannot decode Char from multi-character bytestring"
|
|
|
|
byteStringDecodeBool :: ByteString -> Either String Bool
|
|
byteStringDecodeBool b
|
|
| b == BC8.pack "true" = Right True
|
|
| b == BC8.pack "false" = Right False
|
|
| otherwise = Left "must be true or false"
|
|
|
|
byteStringEncodeChar :: Char -> ByteString
|
|
byteStringEncodeChar = BC8.singleton
|
|
|
|
byteStringEncodeInt :: Int -> ByteString
|
|
byteStringEncodeInt = LByteString.toStrict
|
|
. Builder.toLazyByteString
|
|
. Builder.intDec
|
|
|
|
byteStringEncodeBool :: Bool -> ByteString
|
|
byteStringEncodeBool x = case x of
|
|
True -> BC8.pack "true"
|
|
False -> BC8.pack "false"
|
|
|
|
|
|
decodingA :: Decoding Headless ByteString (Int,Char,Bool)
|
|
decodingA = (,,)
|
|
<$> Decoding.headless byteStringDecodeInt
|
|
<*> Decoding.headless byteStringDecodeChar
|
|
<*> Decoding.headless byteStringDecodeBool
|
|
|
|
encodingA :: Encoding Headless ByteString (Int,Char,Bool)
|
|
encodingA = contramap tripleToPairs
|
|
$ divided (Encoding.headless byteStringEncodeInt)
|
|
$ divided (Encoding.headless byteStringEncodeChar)
|
|
$ divided (Encoding.headless byteStringEncodeBool)
|
|
$ conquered
|
|
|
|
tripleToPairs :: (a,b,c) -> (a,(b,(c,())))
|
|
tripleToPairs (a,b,c) = (a,(b,(c,())))
|
|
|
|
propEncodeDecodeIso :: Eq a => (a -> b) -> (b -> Maybe a) -> a -> Bool
|
|
propEncodeDecodeIso f g a = g (f a) == Just a
|
|
|
|
propMatching :: Eq b => (a -> b) -> (a -> b) -> a -> Bool
|
|
propMatching f g a = f a == g a
|
|
|