-- -- Copyright © 2013-2014 Anchor Systems, Pty Ltd and Others -- -- The code in this file, and the program it is a part of, is -- made available to you by its authors as open source software: -- you can redistribute it and/or modify it under the terms of -- the 3-clause BSD licence. -- {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE TupleSections #-} module Vaultaire.Types.Common ( Origin(..), makeOrigin, Epoch, NumBuckets ) where import Control.Applicative import Control.Exception (Exception, SomeException (..)) import Data.ByteString (ByteString) import qualified Data.ByteString.Char8 as S import Data.Char import Data.Either import Data.Hashable (Hashable) import Data.Locator import Data.String (IsString) import Data.Typeable (Typeable) import Data.Word (Word64) import Test.QuickCheck -- |Origin is a ByteString representing a data origin. It must be -- between one and eight bytes. newtype Origin = Origin { unOrigin :: ByteString } deriving (Eq, Ord, IsString, Hashable) instance Arbitrary Origin where -- suchThat condition should be removed once locators package is fixed arbitrary = Origin . S.pack . toLocator16a 6 <$> arbitrary `suchThat` (>0) instance Read Origin where readsPrec _ = fmap (,"") . rights . (:[]) . makeOrigin . S.pack instance Show Origin where show = S.unpack . unOrigin -- | Invalid origin Exception data BadOrigin = NullOrigin | NonAlphaNumOrigin | OriginTooLong deriving (Show, Typeable) instance Exception BadOrigin makeOrigin :: ByteString -> Either SomeException Origin makeOrigin bs | S.null bs = Left (SomeException NullOrigin) | S.any (not . isAlphaNum) bs = Left (SomeException NonAlphaNumOrigin) | S.length bs > 8 = Left (SomeException OriginTooLong) | otherwise = Right (Origin bs) -- These can all be newtype wrapped as make work, perhaps excluding DayMap. -- They have no reason to be inter-mixed. type Epoch = Word64 type NumBuckets = Word64