{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskellQuotes #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE UndecidableInstances #-}
#if !MIN_VERSION_base(4,17,1)
{-# LANGUAGE TypeFamilies #-}
#endif
{-# OPTIONS_GHC -Wall -fno-warn-redundant-constraints #-}

-- |
-- Module      : Data.Trade.GTIN
-- Description : A module to parse, render and manipulate GTIN codes used for trade and EAN barcodes.
-- Maintainer  : hapytexeu+gh@gmail.com
-- Stability   : experimental
-- Portability : POSIX
--
-- The module exposes a 'GTIN' data type that contains the number of digits as well.
module Data.Trade.GTIN
  ( -- * GTIN and its aliasses.
    GTIN (GTIN),
    gtin,
    GTIN14,
    GTIN13,
    GTIN12,
    GTIN8,
    EANUCC14,
    SCC14,
    EAN,
    EANUCC13,
    ISBN,
    ISBN13,
    EANUCC8,
    GSIN,
    SSCC,

    -- * Check if two GTINs are equivalent, even if the "width" of the GTINs are equivalent.
    equivGTIN,
    upscaleGTIN,

    -- * Fix the checksum of a GTIN number
    fixChecksum,
    checkChecksum,

    -- * Convert the GTINs to a readable format.
    gtinToString,

    -- * ISBN-10 to ISBN-13
    fromISBN10',

    -- * Parsing GTINs
    gtinParser,
    gtinParser_,
    gtinParser',
    gtinParser_',
    parseGTIN,
    parseGTIN_,
    parseGTIN',
    parseGTIN_',

    -- * QuasiQuoters
    gtinQ,
    gtin14Q,
    gtin13Q,
    gtin12Q,
    gtin8Q,
    eanucc8Q,
    eanucc14Q,
    scc14Q,
    eanQ,
    eanucc13Q,
    gsinQ,
    ssccQ,
    isbnQ,
    isbn13Q,
  )
where

import Control.Monad ((>=>))
#if !MIN_VERSION_base(4,13,0)
import Control.Monad.Fail(MonadFail)
#endif
import Data.Binary (Binary (get, put))
import Data.Char (chr, digitToInt)
import Data.Data (Data)
import Data.Functor.Identity (Identity)
import Data.Hashable (Hashable)
import Data.List (unfoldr)
import Data.Proxy (Proxy (Proxy))
import Data.Typeable (Typeable)
#if MIN_VERSION_validity(0,9,0)
import Data.Validity (Validity (validate), check, prettyValidate)
#else
import Data.Validity (Validation(Validation), Validity (validate), check)
#endif
import Data.Word (Word64)
import GHC.Generics (Generic)
#if MIN_VERSION_base(4,16,4)
import Numeric.Natural (Natural)
#else
import GHC.Types(Nat)
#endif
import GHC.TypeNats (KnownNat, natVal)
import qualified GHC.TypeNats as TN
import Language.Haskell.TH.Quote (QuasiQuoter (QuasiQuoter, quoteDec, quoteExp, quotePat, quoteType))
import Test.QuickCheck.Arbitrary (Arbitrary (arbitrary))
import Test.QuickCheck.Gen (choose)
import Text.Parsec (ParseError)
import Text.Parsec.Char (digit, space)
import Text.Parsec.Combinator (eof)
import Text.Parsec.Prim (ParsecT, Stream, runParser, skipMany)
import Text.Printf (PrintfArg, printf)

#if MIN_VERSION_template_haskell(2, 17, 0)
import Language.Haskell.TH.Syntax (Code (Code), Exp (AppE, ConE, LitE), Lift (lift, liftTyped), Lit (IntegerL), Pat (ConP, LitP), TExp (TExp))
#elif MIN_VERSION_template_haskell(2, 16, 0)
import Language.Haskell.TH.Syntax (Exp (AppE, ConE, LitE), Lift (lift, liftTyped), Lit (IntegerL), Pat (ConP, LitP), TExp (TExp))
#else
import Language.Haskell.TH.Syntax (Exp (AppE, ConE, LitE), Lift (lift), Lit (IntegerL), Pat (ConP, LitP))
#endif

#if MIN_VERSION_base(4,16,4)
-- | A datatype for /Global Trade Item Numbers 'GTIN'/ with arbitrary "width" (up to nineteen digits technically possible).
newtype GTIN (n :: Natural) = GTIN Word64 deriving (Typeable (GTIN n)
Typeable (GTIN n)
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> GTIN n -> c (GTIN n))
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (GTIN n))
-> (GTIN n -> Constr)
-> (GTIN n -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (GTIN n)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (GTIN n)))
-> ((forall b. Data b => b -> b) -> GTIN n -> GTIN n)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> GTIN n -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> GTIN n -> r)
-> (forall u. (forall d. Data d => d -> u) -> GTIN n -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> GTIN n -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> GTIN n -> m (GTIN n))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> GTIN n -> m (GTIN n))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> GTIN n -> m (GTIN n))
-> Data (GTIN n)
GTIN n -> Constr
GTIN n -> DataType
(forall b. Data b => b -> b) -> GTIN n -> GTIN n
forall {n :: Natural}. KnownNat n => Typeable (GTIN n)
forall (n :: Natural). KnownNat n => GTIN n -> Constr
forall (n :: Natural). KnownNat n => GTIN n -> DataType
forall (n :: Natural).
KnownNat n =>
(forall b. Data b => b -> b) -> GTIN n -> GTIN n
forall (n :: Natural) u.
KnownNat n =>
Int -> (forall d. Data d => d -> u) -> GTIN n -> u
forall (n :: Natural) u.
KnownNat n =>
(forall d. Data d => d -> u) -> GTIN n -> [u]
forall (n :: Natural) r r'.
KnownNat n =>
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> GTIN n -> r
forall (n :: Natural) r r'.
KnownNat n =>
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> GTIN n -> r
forall (n :: Natural) (m :: * -> *).
(KnownNat n, Monad m) =>
(forall d. Data d => d -> m d) -> GTIN n -> m (GTIN n)
forall (n :: Natural) (m :: * -> *).
(KnownNat n, MonadPlus m) =>
(forall d. Data d => d -> m d) -> GTIN n -> m (GTIN n)
forall (n :: Natural) (c :: * -> *).
KnownNat n =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (GTIN n)
forall (n :: Natural) (c :: * -> *).
KnownNat n =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> GTIN n -> c (GTIN n)
forall (n :: Natural) (t :: * -> *) (c :: * -> *).
(KnownNat n, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (GTIN n))
forall (n :: Natural) (t :: * -> * -> *) (c :: * -> *).
(KnownNat n, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (GTIN n))
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> GTIN n -> u
forall u. (forall d. Data d => d -> u) -> GTIN n -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> GTIN n -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> GTIN n -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> GTIN n -> m (GTIN n)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> GTIN n -> m (GTIN n)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (GTIN n)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> GTIN n -> c (GTIN n)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (GTIN n))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (GTIN n))
$cgfoldl :: forall (n :: Natural) (c :: * -> *).
KnownNat n =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> GTIN n -> c (GTIN n)
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> GTIN n -> c (GTIN n)
$cgunfold :: forall (n :: Natural) (c :: * -> *).
KnownNat n =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (GTIN n)
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (GTIN n)
$ctoConstr :: forall (n :: Natural). KnownNat n => GTIN n -> Constr
toConstr :: GTIN n -> Constr
$cdataTypeOf :: forall (n :: Natural). KnownNat n => GTIN n -> DataType
dataTypeOf :: GTIN n -> DataType
$cdataCast1 :: forall (n :: Natural) (t :: * -> *) (c :: * -> *).
(KnownNat n, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (GTIN n))
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (GTIN n))
$cdataCast2 :: forall (n :: Natural) (t :: * -> * -> *) (c :: * -> *).
(KnownNat n, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (GTIN n))
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (GTIN n))
$cgmapT :: forall (n :: Natural).
KnownNat n =>
(forall b. Data b => b -> b) -> GTIN n -> GTIN n
gmapT :: (forall b. Data b => b -> b) -> GTIN n -> GTIN n
$cgmapQl :: forall (n :: Natural) r r'.
KnownNat n =>
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> GTIN n -> r
gmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> GTIN n -> r
$cgmapQr :: forall (n :: Natural) r r'.
KnownNat n =>
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> GTIN n -> r
gmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> GTIN n -> r
$cgmapQ :: forall (n :: Natural) u.
KnownNat n =>
(forall d. Data d => d -> u) -> GTIN n -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> GTIN n -> [u]
$cgmapQi :: forall (n :: Natural) u.
KnownNat n =>
Int -> (forall d. Data d => d -> u) -> GTIN n -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> GTIN n -> u
$cgmapM :: forall (n :: Natural) (m :: * -> *).
(KnownNat n, Monad m) =>
(forall d. Data d => d -> m d) -> GTIN n -> m (GTIN n)
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> GTIN n -> m (GTIN n)
$cgmapMp :: forall (n :: Natural) (m :: * -> *).
(KnownNat n, MonadPlus m) =>
(forall d. Data d => d -> m d) -> GTIN n -> m (GTIN n)
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> GTIN n -> m (GTIN n)
$cgmapMo :: forall (n :: Natural) (m :: * -> *).
(KnownNat n, MonadPlus m) =>
(forall d. Data d => d -> m d) -> GTIN n -> m (GTIN n)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> GTIN n -> m (GTIN n)
Data, GTIN n -> GTIN n -> Bool
(GTIN n -> GTIN n -> Bool)
-> (GTIN n -> GTIN n -> Bool) -> Eq (GTIN n)
forall (n :: Natural). GTIN n -> GTIN n -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall (n :: Natural). GTIN n -> GTIN n -> Bool
== :: GTIN n -> GTIN n -> Bool
$c/= :: forall (n :: Natural). GTIN n -> GTIN n -> Bool
/= :: GTIN n -> GTIN n -> Bool
Eq, (forall x. GTIN n -> Rep (GTIN n) x)
-> (forall x. Rep (GTIN n) x -> GTIN n) -> Generic (GTIN n)
forall (n :: Natural) x. Rep (GTIN n) x -> GTIN n
forall (n :: Natural) x. GTIN n -> Rep (GTIN n) x
forall x. Rep (GTIN n) x -> GTIN n
forall x. GTIN n -> Rep (GTIN n) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall (n :: Natural) x. GTIN n -> Rep (GTIN n) x
from :: forall x. GTIN n -> Rep (GTIN n) x
$cto :: forall (n :: Natural) x. Rep (GTIN n) x -> GTIN n
to :: forall x. Rep (GTIN n) x -> GTIN n
Generic, Eq (GTIN n)
Eq (GTIN n)
-> (GTIN n -> GTIN n -> Ordering)
-> (GTIN n -> GTIN n -> Bool)
-> (GTIN n -> GTIN n -> Bool)
-> (GTIN n -> GTIN n -> Bool)
-> (GTIN n -> GTIN n -> Bool)
-> (GTIN n -> GTIN n -> GTIN n)
-> (GTIN n -> GTIN n -> GTIN n)
-> Ord (GTIN n)
GTIN n -> GTIN n -> Bool
GTIN n -> GTIN n -> Ordering
GTIN n -> GTIN n -> GTIN n
forall (n :: Natural). Eq (GTIN n)
forall (n :: Natural). GTIN n -> GTIN n -> Bool
forall (n :: Natural). GTIN n -> GTIN n -> Ordering
forall (n :: Natural). GTIN n -> GTIN n -> GTIN n
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: forall (n :: Natural). GTIN n -> GTIN n -> Ordering
compare :: GTIN n -> GTIN n -> Ordering
$c< :: forall (n :: Natural). GTIN n -> GTIN n -> Bool
< :: GTIN n -> GTIN n -> Bool
$c<= :: forall (n :: Natural). GTIN n -> GTIN n -> Bool
<= :: GTIN n -> GTIN n -> Bool
$c> :: forall (n :: Natural). GTIN n -> GTIN n -> Bool
> :: GTIN n -> GTIN n -> Bool
$c>= :: forall (n :: Natural). GTIN n -> GTIN n -> Bool
>= :: GTIN n -> GTIN n -> Bool
$cmax :: forall (n :: Natural). GTIN n -> GTIN n -> GTIN n
max :: GTIN n -> GTIN n -> GTIN n
$cmin :: forall (n :: Natural). GTIN n -> GTIN n -> GTIN n
min :: GTIN n -> GTIN n -> GTIN n
Ord, ReadPrec [GTIN n]
ReadPrec (GTIN n)
Int -> ReadS (GTIN n)
ReadS [GTIN n]
(Int -> ReadS (GTIN n))
-> ReadS [GTIN n]
-> ReadPrec (GTIN n)
-> ReadPrec [GTIN n]
-> Read (GTIN n)
forall (n :: Natural). ReadPrec [GTIN n]
forall (n :: Natural). ReadPrec (GTIN n)
forall (n :: Natural). Int -> ReadS (GTIN n)
forall (n :: Natural). ReadS [GTIN n]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: forall (n :: Natural). Int -> ReadS (GTIN n)
readsPrec :: Int -> ReadS (GTIN n)
$creadList :: forall (n :: Natural). ReadS [GTIN n]
readList :: ReadS [GTIN n]
$creadPrec :: forall (n :: Natural). ReadPrec (GTIN n)
readPrec :: ReadPrec (GTIN n)
$creadListPrec :: forall (n :: Natural). ReadPrec [GTIN n]
readListPrec :: ReadPrec [GTIN n]
Read, Typeable)
#else
-- | A datatype for /Global Trade Item Numbers 'GTIN'/ with arbitrary "width" (up to nineteen digits technically possible).
newtype GTIN (n :: Nat) = GTIN Word64 deriving (Data, Eq, Generic, Ord, Read, Typeable)
#endif

_hole :: GTIN n
_hole :: forall (n :: Natural). GTIN n
_hole = [Char] -> GTIN n
forall a. HasCallStack => [Char] -> a
error [Char]
"should not be evaluated"

_fromEnum :: GTIN n -> Word64
_fromEnum :: forall (n :: Natural). GTIN n -> Word64
_fromEnum (GTIN Word64
w) = Word64
w Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`div` Word64
10

_toEnum :: Word64 -> GTIN n
_toEnum :: forall (n :: Natural). Word64 -> GTIN n
_toEnum = GTIN n -> GTIN n
forall (n :: Natural). GTIN n -> GTIN n
fixChecksum (GTIN n -> GTIN n) -> (Word64 -> GTIN n) -> Word64 -> GTIN n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
GTIN (Word64 -> GTIN n) -> (Word64 -> Word64) -> Word64 -> GTIN n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64
10 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
*)

-- | Constructing a 'GTIN" with bound and checksum checks.
gtin ::
  forall i n.
  ((TN.<=) n 19, Integral i, KnownNat n) =>
  -- | An 'Integral' value for which we want to construct a 'GTIN' number.
  i ->
  -- | A 'GTIN' number wrapped in a 'Just' if the given value is within bounds and the checksum matches; 'Nothing' otherwise.
  Maybe (GTIN n)
gtin :: forall i (n :: Natural).
(n <= 19, Integral i, KnownNat n) =>
i -> Maybe (GTIN n)
gtin i
v''
  | Integer
0 Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
v' Bool -> Bool -> Bool
&& Integer
v' Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
m Bool -> Bool -> Bool
&& GTIN Any -> Bool
forall (n :: Natural). GTIN n -> Bool
checkChecksum GTIN Any
forall (n :: Natural). GTIN n
v = GTIN n -> Maybe (GTIN n)
forall a. a -> Maybe a
Just GTIN n
forall (n :: Natural). GTIN n
v
  | Bool
otherwise = Maybe (GTIN n)
forall a. Maybe a
Nothing
  where
    v' :: Integer
v' = i -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral i
v'' :: Integer
    v :: GTIN n
v = Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
GTIN (Integer -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
v')
    m :: Integer
m = GTIN n -> Integer
forall i (n :: Natural). (Integral i, KnownNat n) => GTIN n -> i
_maxBound (GTIN n
forall (n :: Natural). GTIN n
_hole :: GTIN n)

_decw :: KnownNat n => GTIN n -> Int
_decw :: forall (n :: Natural). KnownNat n => GTIN n -> Int
_decw = Natural -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Natural -> Int) -> (GTIN n -> Natural) -> GTIN n -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GTIN n -> Natural
forall (n :: Natural) (proxy :: Natural -> *).
KnownNat n =>
proxy n -> Natural
natVal

_decw' :: KnownNat n => GTIN n -> Int
_decw' :: forall (n :: Natural). KnownNat n => GTIN n -> Int
_decw' = Int -> Int
forall a. Enum a => a -> a
pred (Int -> Int) -> (GTIN n -> Int) -> GTIN n -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GTIN n -> Int
forall (n :: Natural). KnownNat n => GTIN n -> Int
_decw

_maxBound' :: (Integral i, KnownNat n) => GTIN n -> i
_maxBound' :: forall i (n :: Natural). (Integral i, KnownNat n) => GTIN n -> i
_maxBound' = (i
10 i -> Int -> i
forall a b. (Num a, Integral b) => a -> b -> a
^) (Int -> i) -> (GTIN n -> Int) -> GTIN n -> i
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GTIN n -> Int
forall (n :: Natural). KnownNat n => GTIN n -> Int
_decw

_maxBound'' :: (Integral i, KnownNat n) => GTIN n -> i
_maxBound'' :: forall i (n :: Natural). (Integral i, KnownNat n) => GTIN n -> i
_maxBound'' = (i
10 i -> Int -> i
forall a b. (Num a, Integral b) => a -> b -> a
^) (Int -> i) -> (GTIN n -> Int) -> GTIN n -> i
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GTIN n -> Int
forall (n :: Natural). KnownNat n => GTIN n -> Int
_decw'

_maxBound :: (Integral i, KnownNat n) => GTIN n -> i
_maxBound :: forall i (n :: Natural). (Integral i, KnownNat n) => GTIN n -> i
_maxBound = i -> i
forall a. Enum a => a -> a
pred (i -> i) -> (GTIN n -> i) -> GTIN n -> i
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GTIN n -> i
forall i (n :: Natural). (Integral i, KnownNat n) => GTIN n -> i
_maxBound'

-- | values without checksum digit (so divided by ten)
_modBound :: (Integral i, KnownNat n) => GTIN n -> i -> i
_modBound :: forall i (n :: Natural).
(Integral i, KnownNat n) =>
GTIN n -> i -> i
_modBound = (i -> i -> i) -> i -> i -> i
forall a b c. (a -> b -> c) -> b -> a -> c
flip i -> i -> i
forall a. Integral a => a -> a -> a
mod (i -> i -> i) -> (GTIN n -> i) -> GTIN n -> i -> i
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GTIN n -> i
forall i (n :: Natural). (Integral i, KnownNat n) => GTIN n -> i
_maxBound''

_checkgtin :: Word64 -> GTIN n
_checkgtin :: forall (n :: Natural). Word64 -> GTIN n
_checkgtin = GTIN n -> GTIN n
forall (n :: Natural). GTIN n -> GTIN n
fixChecksum (GTIN n -> GTIN n) -> (Word64 -> GTIN n) -> Word64 -> GTIN n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
GTIN

_checkgtin' :: [Word64] -> [GTIN n]
_checkgtin' :: forall (n :: Natural). [Word64] -> [GTIN n]
_checkgtin' = (Word64 -> GTIN n) -> [Word64] -> [GTIN n]
forall a b. (a -> b) -> [a] -> [b]
map Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
_checkgtin

_wipe :: Word64 -> Word64
_wipe :: Word64 -> Word64
_wipe Word64
w = Word64
w Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
w Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`mod` Word64
10

_tocheck :: Integral i => i -> i -> i
_tocheck :: forall a. Integral a => a -> a -> a
_tocheck i
n i
d = (i
d i -> i -> i
forall a. Num a => a -> a -> a
+ i
n1 i -> i -> i
forall a. Num a => a -> a -> a
+ i
3 i -> i -> i
forall a. Num a => a -> a -> a
* i
n2) i -> i -> i
forall a. Integral a => a -> a -> a
`mod` i
10
  where
    ~(i
n1, i
n2) = i
n i -> i -> (i, i)
forall a. Integral a => a -> a -> (a, a)
`quotRem` i
10

_determineChecksum :: Word64 -> Word64
_determineChecksum :: Word64 -> Word64
_determineChecksum Word64
w = (Word64
10 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
go Word64
w Word64
0) Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`mod` Word64
10
  where
    go :: b -> b -> b
go b
0 = b -> b
forall a. a -> a
id
    go b
n = b -> b -> b
go b
q (b -> b) -> (b -> b) -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> b -> b
forall a. Integral a => a -> a -> a
_tocheck b
r
      where
        ~(b
q, b
r) = b
n b -> b -> (b, b)
forall a. Integral a => a -> a -> (a, a)
`quotRem` b
100

-- | Fix the checksum of a given 'GTIN' object. If the checksum is valid, then it will return the same GTIN, this operation is thus /idempotent/.
fixChecksum ::
  -- | The given 'GTIN' number where we fix the checksum from.
  GTIN n ->
  -- | A 'GTIN' object that is the variant of the given 'GTIN' number, with a valid checksum.
  GTIN n
fixChecksum :: forall (n :: Natural). GTIN n -> GTIN n
fixChecksum (GTIN Word64
w') = Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
GTIN (Word64
w' Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
w1 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64 -> Word64
_determineChecksum Word64
w0)
  where
    ~(Word64
w0, Word64
w1) = Word64
w' Word64 -> Word64 -> (Word64, Word64)
forall a. Integral a => a -> a -> (a, a)
`quotRem` Word64
10

-- | Check if the given checksum matches.
checkChecksum ::
  -- | The given 'GTIN' number for which we check the checksum.
  GTIN n ->
  -- | 'True' if the given checksum matches; 'False' otherwise.
  Bool
checkChecksum :: forall (n :: Natural). GTIN n -> Bool
checkChecksum (GTIN Word64
w') = Word64 -> Word64
_determineChecksum Word64
w0 Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
w1
  where
    ~(Word64
w0, Word64
w1) = Word64
w' Word64 -> Word64 -> (Word64, Word64)
forall a. Integral a => a -> a -> (a, a)
`quotRem` Word64
10

-- | Convert one 'GTIN' into a 'GTIN' that has more digits. The new 'GTIN' will have additional leading zeros.
upscaleGTIN ::
  (TN.<=) m n =>
  -- | The original 'GTIN' number to upscale.
  GTIN m ->
  -- | A 'GTIN' with the same number, but more (or the same) number of digits.
  GTIN n
upscaleGTIN :: forall (m :: Natural) (n :: Natural). (m <= n) => GTIN m -> GTIN n
upscaleGTIN (GTIN Word64
w) = Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
GTIN Word64
w

-- | Check if two 'GTIN' numbers, possibly with a different "width" are equivalent.
equivGTIN ::
  -- | The first 'GTIN' to check.
  GTIN m ->
  -- | The second 'GTIN' to check.
  GTIN n ->
  -- | 'True' if the given 'GTIN' values are equivalent; 'False' otherwise.
  Bool
equivGTIN :: forall (m :: Natural) (n :: Natural). GTIN m -> GTIN n -> Bool
equivGTIN (GTIN Word64
w1) (GTIN Word64
w2) = Word64
w1 Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
w2

instance KnownNat n => Validity (GTIN n) where
  validate :: GTIN n -> Validation
validate g :: GTIN n
g@(GTIN Word64
w) =
    Bool -> [Char] -> Validation
check (Word64
w Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= GTIN n -> Word64
forall i (n :: Natural). (Integral i, KnownNat n) => GTIN n -> i
_maxBound GTIN n
g) [Char]
"The value is larger than the maximum number of digits."
      Validation -> Validation -> Validation
forall a. Monoid a => a -> a -> a
`mappend` Bool -> [Char] -> Validation
check (GTIN n -> Bool
forall (n :: Natural). GTIN n -> Bool
checkChecksum GTIN n
g) ([Char]
"checksum does not match: expected " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
pf [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Word64 -> Char
cc Word64
c' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Char]
", but got " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
pf [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Word64 -> Char
cc Word64
w0 Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Char]
".")
    where
      ~(Word64
w', Word64
w0) = Word64
w Word64 -> Word64 -> (Word64, Word64)
forall a. Integral a => a -> a -> (a, a)
`divMod` Word64
10
      c' :: Word64
c' = Word64 -> Word64
_determineChecksum Word64
w'
      pf :: [Char]
pf = Int -> Word64 -> [Char]
forall i j. (Integral i, Show i, PrintfArg j) => i -> j -> [Char]
_printf (GTIN n -> Int
forall (n :: Natural). KnownNat n => GTIN n -> Int
_decw' GTIN n
g) Word64
w'
      cc :: Word64 -> Char
cc = Int -> Char
chr (Int -> Char) -> (Word64 -> Int) -> Word64 -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int
0x1d7ce Int -> Int -> Int
forall a. Num a => a -> a -> a
+) (Int -> Int) -> (Word64 -> Int) -> Word64 -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral

_printf :: (Integral i, Show i, PrintfArg j) => i -> j -> String
_printf :: forall i j. (Integral i, Show i, PrintfArg j) => i -> j -> [Char]
_printf = [Char] -> j -> [Char]
forall r. PrintfType r => [Char] -> r
printf ([Char] -> j -> [Char]) -> (i -> [Char]) -> i -> j -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char]
"%0" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++) ([Char] -> [Char]) -> (i -> [Char]) -> i -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"d") ([Char] -> [Char]) -> (i -> [Char]) -> i -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> [Char]
forall a. Show a => a -> [Char]
show

_printf' :: (KnownNat n, PrintfArg j) => GTIN n -> j -> String
_printf' :: forall (n :: Natural) j.
(KnownNat n, PrintfArg j) =>
GTIN n -> j -> [Char]
_printf' = Int -> j -> [Char]
forall i j. (Integral i, Show i, PrintfArg j) => i -> j -> [Char]
_printf (Int -> j -> [Char]) -> (GTIN n -> Int) -> GTIN n -> j -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GTIN n -> Int
forall (n :: Natural). KnownNat n => GTIN n -> Int
_decw

instance KnownNat n => Show (GTIN n) where
  showsPrec :: Int -> GTIN n -> [Char] -> [Char]
showsPrec Int
d g :: GTIN n
g@(GTIN Word64
v) = Bool -> ([Char] -> [Char]) -> [Char] -> [Char]
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0) (([Char]
"GTIN " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> Word64 -> [Char]
forall r. PrintfType r => [Char] -> r
printf ([Char]
"%0" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
sn [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"d") Word64
v [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" :: GTIN " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
sn) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++)
    where
      sn :: [Char]
sn = Int -> [Char]
forall a. Show a => a -> [Char]
show (GTIN n -> Int
forall (n :: Natural). KnownNat n => GTIN n -> Int
_decw GTIN n
g)

-- | Convert the given 'GTIN' number to convert to a 'String' that groups numbers into groups of four.
gtinToString ::
  KnownNat n =>
  -- | The given 'GTIN' number to convert to a readable 'String'.
  GTIN n ->
  -- | A 'String' that contains the GTIN number, in chucks of four digits.
  String
gtinToString :: forall (n :: Natural). KnownNat n => GTIN n -> [Char]
gtinToString g :: GTIN n
g@(GTIN Word64
w) = [[Char]] -> [Char]
unwords (((Int, Word64) -> [Char]) -> [(Int, Word64)] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map (Int, Word64) -> [Char]
forall {t} {t} {a}.
(PrintfArg t, PrintfType t, Show a) =>
(a, t) -> t
p ([(Int, Word64)] -> [(Int, Word64)]
forall a. [a] -> [a]
reverse (((Int, Word64) -> Maybe ((Int, Word64), (Int, Word64)))
-> (Int, Word64) -> [(Int, Word64)]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
unfoldr (Int, Word64) -> Maybe ((Int, Word64), (Int, Word64))
forall {b}. Integral b => (Int, b) -> Maybe ((Int, b), (Int, b))
f (Int
n, Word64
w))))
  where
    n :: Int
n = GTIN n -> Int
forall (n :: Natural). KnownNat n => GTIN n -> Int
_decw GTIN n
g
    ww' :: Int
ww' = Int
n Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2
    ww :: Int
ww = Int
ww' Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
ww' Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
2
    p :: (a, t) -> t
p (a
n0, t
v) = [Char] -> t -> t
forall r. PrintfType r => [Char] -> r
printf ([Char]
"%0" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ a -> [Char]
forall a. Show a => a -> [Char]
show a
n0 [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"d") t
v
    f :: (Int, b) -> Maybe ((Int, b), (Int, b))
f (Int
n0, b
v)
      | Int
n0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = Maybe ((Int, b), (Int, b))
forall a. Maybe a
Nothing
      | Bool
otherwise = ((Int, b), (Int, b)) -> Maybe ((Int, b), (Int, b))
forall a. a -> Maybe a
Just ((Int
dd, b
r), (Int
n0 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
dd, b
q))
      where
        ~(b
q, b
r) = b
v b -> b -> (b, b)
forall a. Integral a => a -> a -> (a, a)
`quotRem` b
10000
        dd :: Int
dd = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
ww Int
n0

instance ((TN.<=) n 19, KnownNat n) => Num (GTIN n) where
  GTIN n
g1 + :: GTIN n -> GTIN n -> GTIN n
+ GTIN n
g2 = Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
_toEnum (GTIN n -> Word64 -> Word64
forall i (n :: Natural).
(Integral i, KnownNat n) =>
GTIN n -> i -> i
_modBound GTIN n
g1 (GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum GTIN n
g1 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum GTIN n
g2)) -- can handle overflow, since we first omit the checksum
  GTIN n
g1 - :: GTIN n -> GTIN n -> GTIN n
- GTIN n
g2 = Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
_toEnum (GTIN n -> Word64 -> Word64
forall i (n :: Natural).
(Integral i, KnownNat n) =>
GTIN n -> i -> i
_modBound GTIN n
g1 (GTIN n -> Word64
forall i (n :: Natural). (Integral i, KnownNat n) => GTIN n -> i
_maxBound'' GTIN n
g1 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum GTIN n
g1 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum GTIN n
g2))
  GTIN n
g1 * :: GTIN n -> GTIN n -> GTIN n
* GTIN n
g2 = Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
_toEnum (Integer -> Word64
forall a. Num a => Integer -> a
fromInteger (GTIN n -> Integer -> Integer
forall i (n :: Natural).
(Integral i, KnownNat n) =>
GTIN n -> i -> i
_modBound GTIN n
g1 (GTIN n -> Integer
forall {n :: Natural}. GTIN n -> Integer
fe GTIN n
g1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* GTIN n -> Integer
forall {n :: Natural}. GTIN n -> Integer
fe GTIN n
g2)))
    where
      fe :: GTIN n -> Integer
fe = Word64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Integer) -> (GTIN n -> Word64) -> GTIN n -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum
  negate :: GTIN n -> GTIN n
negate GTIN n
g = Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
_toEnum (GTIN n -> Word64 -> Word64
forall i (n :: Natural).
(Integral i, KnownNat n) =>
GTIN n -> i -> i
_modBound GTIN n
g (GTIN n -> Word64
forall i (n :: Natural). (Integral i, KnownNat n) => GTIN n -> i
_maxBound'' GTIN n
g Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum GTIN n
g))
  abs :: GTIN n -> GTIN n
abs = GTIN n -> GTIN n
forall a. a -> a
id
  signum :: GTIN n -> GTIN n
signum = Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
_toEnum (Word64 -> GTIN n) -> (GTIN n -> Word64) -> GTIN n -> GTIN n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Word64
forall a. Num a => a -> a
signum (Word64 -> Word64) -> (GTIN n -> Word64) -> GTIN n -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum
  fromInteger :: Integer -> GTIN n
fromInteger Integer
w = GTIN n
v
    where
      v :: GTIN n
v = Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
_toEnum (Integer -> Word64
forall a. Num a => Integer -> a
fromInteger (GTIN n -> Integer -> Integer
forall i (n :: Natural).
(Integral i, KnownNat n) =>
GTIN n -> i -> i
_modBound GTIN n
v Integer
w))

instance ((TN.<=) n 19, KnownNat n) => Real (GTIN n) where
  toRational :: GTIN n -> Rational
toRational = Word64 -> Rational
forall a. Real a => a -> Rational
toRational (Word64 -> Rational) -> (GTIN n -> Word64) -> GTIN n -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum

instance ((TN.<=) n 19, KnownNat n) => Integral (GTIN n) where
  toInteger :: GTIN n -> Integer
toInteger = Word64 -> Integer
forall a. Integral a => a -> Integer
toInteger (Word64 -> Integer) -> (GTIN n -> Word64) -> GTIN n -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum
  GTIN n
g1 quotRem :: GTIN n -> GTIN n -> (GTIN n, GTIN n)
`quotRem` GTIN n
g2 = (Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
_toEnum Word64
q, Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
_toEnum Word64
r)
    where
      ~(Word64
q, Word64
r) = GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum GTIN n
g1 Word64 -> Word64 -> (Word64, Word64)
forall a. Integral a => a -> a -> (a, a)
`quotRem` GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum GTIN n
g2
  GTIN n
g1 divMod :: GTIN n -> GTIN n -> (GTIN n, GTIN n)
`divMod` GTIN n
g2 = (Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
_toEnum Word64
d, Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
_toEnum Word64
m)
    where
      ~(Word64
d, Word64
m) = GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum GTIN n
g1 Word64 -> Word64 -> (Word64, Word64)
forall a. Integral a => a -> a -> (a, a)
`divMod` GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum GTIN n
g2
  GTIN n
g1 quot :: GTIN n -> GTIN n -> GTIN n
`quot` GTIN n
g2 = Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
_toEnum (GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum GTIN n
g1 Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`quot` GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum GTIN n
g2)
  GTIN n
g1 rem :: GTIN n -> GTIN n -> GTIN n
`rem` GTIN n
g2 = Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
_toEnum (GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum GTIN n
g1 Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`rem` GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum GTIN n
g2)
  GTIN n
g1 div :: GTIN n -> GTIN n -> GTIN n
`div` GTIN n
g2 = Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
_toEnum (GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum GTIN n
g1 Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`div` GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum GTIN n
g2)
  GTIN n
g1 mod :: GTIN n -> GTIN n -> GTIN n
`mod` GTIN n
g2 = Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
_toEnum (GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum GTIN n
g1 Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`mod` GTIN n -> Word64
forall (n :: Natural). GTIN n -> Word64
_fromEnum GTIN n
g2)

instance ((TN.<=) n 19, KnownNat n) => Arbitrary (GTIN n) where
  arbitrary :: Gen (GTIN n)
arbitrary = Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
_toEnum (Word64 -> GTIN n) -> Gen Word64 -> Gen (GTIN n)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Word64, Word64) -> Gen Word64
forall a. Random a => (a, a) -> Gen a
choose (Word64
0, GTIN n -> Word64
forall i (n :: Natural). (Integral i, KnownNat n) => GTIN n -> i
_maxBound'' (GTIN n
forall (n :: Natural). GTIN n
_hole :: GTIN n) Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
1)

instance Hashable (GTIN n)

instance Binary (GTIN n) where
  get :: Get (GTIN n)
get = Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
GTIN (Word64 -> GTIN n) -> Get Word64 -> Get (GTIN n)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word64
forall t. Binary t => Get t
get
  put :: GTIN n -> Put
put (GTIN Word64
w) = Word64 -> Put
forall t. Binary t => t -> Put
put Word64
w

#if MIN_VERSION_base(4,16,4)
instance KnownNat n => Bounded (GTIN (n :: Natural)) where
  minBound :: GTIN n
minBound = GTIN n -> GTIN n
forall (n :: Natural). GTIN n -> GTIN n
fixChecksum (Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
GTIN Word64
0)
  maxBound :: GTIN n
maxBound = GTIN n -> GTIN n
forall (n :: Natural). GTIN n -> GTIN n
fixChecksum (Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
GTIN (Word64
10 Word64 -> Int -> Word64
forall a b. (Num a, Integral b) => a -> b -> a
^ GTIN n -> Int
forall (n :: Natural). KnownNat n => GTIN n -> Int
_decw (GTIN n
forall (n :: Natural). GTIN n
_hole :: GTIN n) Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
1))
#else
instance KnownNat n => Bounded (GTIN (n :: Nat)) where
  minBound = fixChecksum (GTIN 0)
  maxBound = fixChecksum (GTIN (10 ^ _decw (_hole :: GTIN n) - 1))
#endif

#if MIN_VERSION_base(4,16,4)
instance KnownNat n => Enum (GTIN (n :: Natural)) where
  succ :: GTIN n -> GTIN n
succ (GTIN Word64
w) = GTIN n -> GTIN n
forall (n :: Natural). GTIN n -> GTIN n
fixChecksum (Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
GTIN (Word64
w Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
10))
  pred :: GTIN n -> GTIN n
pred (GTIN Word64
w) = GTIN n -> GTIN n
forall (n :: Natural). GTIN n -> GTIN n
fixChecksum (Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
GTIN (Word64
w Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
10))
  toEnum :: Int -> GTIN n
toEnum = Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
GTIN (Word64 -> GTIN n) -> (Int -> Word64) -> Int -> GTIN n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Word64
forall a. Enum a => Int -> a
toEnum
  fromEnum :: GTIN n -> Int
fromEnum (GTIN Word64
w) = Word64 -> Int
forall a. Enum a => a -> Int
fromEnum Word64
w
  enumFrom :: GTIN n -> [GTIN n]
enumFrom g :: GTIN n
g@(GTIN Word64
n) = [Word64] -> [GTIN n]
forall (n :: Natural). [Word64] -> [GTIN n]
_checkgtin' [Word64
n, Word64
n Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
10 .. GTIN n -> Word64
forall i (n :: Natural). (Integral i, KnownNat n) => GTIN n -> i
_maxBound GTIN n
g]
  enumFromThen :: GTIN n -> GTIN n -> [GTIN n]
enumFromThen g :: GTIN n
g@(GTIN Word64
m) (GTIN Word64
n)
    | Word64
m Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64
n = [Word64] -> [GTIN n]
forall (n :: Natural). [Word64] -> [GTIN n]
_checkgtin' [Word64 -> Word64
_wipe Word64
m, Word64 -> Word64
_wipe Word64
n .. GTIN n -> Word64
forall i (n :: Natural). (Integral i, KnownNat n) => GTIN n -> i
_maxBound GTIN n
g]
    | Bool
otherwise = [Word64] -> [GTIN n]
forall (n :: Natural). [Word64] -> [GTIN n]
_checkgtin' [Word64 -> Word64
_wipe Word64
m, Word64 -> Word64
_wipe Word64
n .. Word64
0]
  enumFromThenTo :: GTIN n -> GTIN n -> GTIN n -> [GTIN n]
enumFromThenTo (GTIN Word64
m) (GTIN Word64
n) (GTIN Word64
o) = [Word64] -> [GTIN n]
forall (n :: Natural). [Word64] -> [GTIN n]
_checkgtin' [Word64 -> Word64
_wipe Word64
m, Word64 -> Word64
_wipe Word64
n .. Word64 -> Word64
_wipe Word64
o]
  enumFromTo :: GTIN n -> GTIN n -> [GTIN n]
enumFromTo (GTIN Word64
m) (GTIN Word64
n) = (Word64 -> GTIN n) -> [Word64] -> [GTIN n]
forall a b. (a -> b) -> [a] -> [b]
map (GTIN n -> GTIN n
forall (n :: Natural). GTIN n -> GTIN n
fixChecksum (GTIN n -> GTIN n) -> (Word64 -> GTIN n) -> Word64 -> GTIN n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
GTIN) [Word64
m, Word64
m Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
10 .. Word64
n]
#else
instance KnownNat n => Enum (GTIN (n :: Nat)) where
  succ (GTIN w) = fixChecksum (GTIN (w + 10))
  pred (GTIN w) = fixChecksum (GTIN (w - 10))
  toEnum = GTIN . toEnum
  fromEnum (GTIN w) = fromEnum w
  enumFrom g@(GTIN n) = _checkgtin' [n, n + 10 .. _maxBound g]
  enumFromThen g@(GTIN m) (GTIN n)
    | m <= n = _checkgtin' [_wipe m, _wipe n .. _maxBound g]
    | otherwise = _checkgtin' [_wipe m, _wipe n .. 0]
  enumFromThenTo (GTIN m) (GTIN n) (GTIN o) = _checkgtin' [_wipe m, _wipe n .. _wipe o]
  enumFromTo (GTIN m) (GTIN n) = map (fixChecksum . GTIN) [m, m + 10 .. n]
#endif

instance Lift (GTIN n) where
  lift :: forall (m :: * -> *). Quote m => GTIN n -> m Exp
lift (GTIN Word64
w) = Exp -> m Exp
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Name -> Exp
ConE 'GTIN Exp -> Exp -> Exp
`AppE` Lit -> Exp
LitE (Integer -> Lit
IntegerL (Word64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
w)))

#if MIN_VERSION_template_haskell(2, 17, 0)
  liftTyped :: forall (m :: * -> *). Quote m => GTIN n -> Code m (GTIN n)
liftTyped (GTIN Word64
w) = m (TExp (GTIN n)) -> Code m (GTIN n)
forall (m :: * -> *) a. m (TExp a) -> Code m a
Code (TExp (GTIN n) -> m (TExp (GTIN n))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Exp -> TExp (GTIN n)
forall a. Exp -> TExp a
TExp (Name -> Exp
ConE 'GTIN Exp -> Exp -> Exp
`AppE` (Lit -> Exp
LitE (Integer -> Lit
IntegerL (Word64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
w))))))
#elif MIN_VERSION_template_haskell(2, 16, 0)
  liftTyped (GTIN w) = pure (TExp (ConE 'GTIN `AppE` (LitE (IntegerL (fromIntegral w)))))
#endif

-- | A type alias for a 'GTIN' number with fourteen numbers, with as range @00 0000 0000 0000@–@99 9999 9999 9997@.
type GTIN14 = GTIN 14

-- | A type alias for a 'GTIN' number with thirteen numbers, with as range @0 0000 0000 0000@–@9 9999 9999 9994@.
type GTIN13 = GTIN 13

-- | A type alias for a 'GTIN' number with twelve numbers, with as range @0000 0000 0000@–@9999 9999 9993@.
type GTIN12 = GTIN 12

-- | A type alias for a 'GTIN' number with eight numbers, with as range @0000 0000@–@9999 9995@.
type GTIN8 = GTIN 8

-- | A type alias for a 'GTIN' number with seventeen numbers, with as range @0 0000 0000 0000 0000@–@9 9999 9999 9999 9992@.
type GSIN = GTIN 17

-- | A type alias for a 'GTIN' number with eighteen numbers, with as range @00 0000 0000 0000 0000@–@99 9999 9999 9999 9995@.
type SSCC = GTIN 18

-- | A type alias for a 'GTIN' number with fourteen numbers, with as range @00 0000 0000 0000@–@99 9999 9999 9997@.
type EANUCC14 = GTIN14

-- | A type alias for a 'GTIN' number with fourteen numbers, with as range @00 0000 0000 0000@–@99 9999 9999 9997@.
type SCC14 = GTIN14

-- | A type alias for a 'GTIN' number with thirteen numbers, with as range @0 0000 0000 0000@–@9 9999 9999 9994@.
type EAN = GTIN13

-- | A type alias for a 'GTIN' number with thirteen numbers, with as range @0 0000 0000 0000@–@9 9999 9999 9994@.
type EANUCC13 = GTIN13

-- | A type alias for a 'GTIN' with thirtheen numbers which is also an ISBN number, with as range @0 0000 0000 0000@–@9 9999 9999 9994@.
type ISBN = GTIN13

-- | A type alias for a 'GTIN' with thirtheen numbers which is also an ISBN number, with as range @0 0000 0000 0000@–@9 9999 9999 9994@.
type ISBN13 = GTIN13

-- | A type alias for a 'GTIN' number with eight numbers, with as range @0000 0000@–@9999 9995@.
type EANUCC8 = GTIN8

-- | Convert a given integral number that contains an ISBN-10 number into the 'ISBN13' equivalent. For example @8175257660@ is converted to @9 7881 7525 7665@. This will add a @978@ prefix,
-- and recalculate the checksum.
fromISBN10' ::
  Integral i =>
  -- | An 'Integral' number that contains an ISBN-10.
  i ->
  -- | The equivalent ISBN-13 number, which is a 'GTIN' number with the corresponding checksum algorithm.
  ISBN13
fromISBN10' :: forall i. Integral i => i -> ISBN13
fromISBN10' = ISBN13 -> ISBN13
forall (n :: Natural). GTIN n -> GTIN n
fixChecksum (ISBN13 -> ISBN13) -> (i -> ISBN13) -> i -> ISBN13
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> ISBN13
forall (n :: Natural). Word64 -> GTIN n
GTIN (Word64 -> ISBN13) -> (i -> Word64) -> i -> ISBN13
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64
9780000000000 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+) (Word64 -> Word64) -> (i -> Word64) -> i -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral

#if !MIN_VERSION_validity(0,9,0)
prettyValidate :: Validity a => a -> Either String a
prettyValidate a = go (validate a)
  where go (Validation []) = Right a
        go v = Left (show v)
#endif

#if MIN_VERSION_template_haskell(2, 18, 0)
_toPattern :: GTIN n -> Pat
_toPattern :: forall (n :: Natural). GTIN n -> Pat
_toPattern (GTIN Word64
w) = Name -> [Type] -> [Pat] -> Pat
ConP 'GTIN [] [Lit -> Pat
LitP (Integer -> Lit
IntegerL (Word64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
w))]
#else
_toPattern :: GTIN n -> Pat
_toPattern (GTIN w) = ConP 'GTIN [LitP (IntegerL (fromIntegral w))]
#endif

_liftEither :: (Show s, MonadFail m) => Either s a -> m a
_liftEither :: forall s (m :: * -> *) a.
(Show s, MonadFail m) =>
Either s a -> m a
_liftEither = (s -> m a) -> (a -> m a) -> Either s a -> m a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ([Char] -> m a
forall a. [Char] -> m a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char] -> m a) -> (s -> [Char]) -> s -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> [Char]
forall a. Show a => a -> [Char]
show) a -> m a
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure

-- | A parser for a gtin number with an arbitrary number of digits between two and nineteen. the parser does not /end/ after the gtin (so no 'eof' is required),
-- and furthermore does /not/ validate if the gtin is indeed valid. The parser parses the number of digits with an arbitrary number of spaces between any two digits.
gtinParser_' ::
  forall s u m n.
  ((TN.<=) 2 n, (TN.<=) n 19, KnownNat n, Stream s m Char) =>
  -- | A parser parsing a GTIN with an arbitrary number of digits that does /not/ force the stream to end, and does /not/ check the checksum.
  ParsecT s u m (GTIN n)
gtinParser_' :: forall s u (m :: * -> *) (n :: Natural).
(2 <= n, n <= 19, KnownNat n, Stream s m Char) =>
ParsecT s u m (GTIN n)
gtinParser_' = Word64 -> GTIN n
forall (n :: Natural). Word64 -> GTIN n
GTIN (Word64 -> GTIN n)
-> ParsecT s u m Word64 -> ParsecT s u m (GTIN n)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT s u m Word64
forall {u}. ParsecT s u m Word64
dd ParsecT s u m Word64
-> (Word64 -> ParsecT s u m Word64) -> ParsecT s u m Word64
forall a b.
ParsecT s u m a -> (a -> ParsecT s u m b) -> ParsecT s u m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Word64 -> ParsecT s u m Word64
forall {t} {u}.
(Eq t, Num t) =>
t -> Word64 -> ParsecT s u m Word64
go (GTIN n -> Int
forall (n :: Natural). KnownNat n => GTIN n -> Int
_decw' (GTIN n
forall (n :: Natural). GTIN n
_hole :: GTIN n)))
  where
    go :: t -> Word64 -> ParsecT s u m Word64
go t
0 Word64
v = Word64 -> ParsecT s u m Word64
forall a. a -> ParsecT s u m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Word64
v
    go t
n Word64
v = (ParsecT s u m Char -> ParsecT s u m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
space ParsecT s u m () -> ParsecT s u m Word64 -> ParsecT s u m Word64
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT s u m Word64
forall {u}. ParsecT s u m Word64
dd) ParsecT s u m Word64
-> (Word64 -> ParsecT s u m Word64) -> ParsecT s u m Word64
forall a b.
ParsecT s u m a -> (a -> ParsecT s u m b) -> ParsecT s u m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= t -> Word64 -> ParsecT s u m Word64
go (t
n t -> t -> t
forall a. Num a => a -> a -> a
- t
1) (Word64 -> ParsecT s u m Word64)
-> (Word64 -> Word64) -> Word64 -> ParsecT s u m Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Word64
10 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
v) Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+)
    dd :: ParsecT s u m Word64
dd = Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word64) -> (Char -> Int) -> Char -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Int
digitToInt (Char -> Word64) -> ParsecT s u m Char -> ParsecT s u m Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit

-- | A parser for a gtin number with an arbitrary number of digits between two and nineteen. the parser does not /end/ after the gtin (so no 'eof' is required).
-- The GTIN is validated, so if the checksum does not match, the parser fails. The parser parses the number of digits with an arbitrary number of spaces between any two digits.
gtinParser_ ::
  forall s u m n.
  ((TN.<=) 2 n, (TN.<=) n 19, KnownNat n, Stream s m Char) =>
  -- | A parser parsing a GTIN with an arbitrary number of digits that does /not/ force the stream to end, but checks the checksum.
  ParsecT s u m (GTIN n)
gtinParser_ :: forall s u (m :: * -> *) (n :: Natural).
(2 <= n, n <= 19, KnownNat n, Stream s m Char) =>
ParsecT s u m (GTIN n)
gtinParser_ = ParsecT s u m (GTIN n)
forall s u (m :: * -> *) (n :: Natural).
(2 <= n, n <= 19, KnownNat n, Stream s m Char) =>
ParsecT s u m (GTIN n)
gtinParser_' ParsecT s u m (GTIN n)
-> (GTIN n -> ParsecT s u m (GTIN n)) -> ParsecT s u m (GTIN n)
forall a b.
ParsecT s u m a -> (a -> ParsecT s u m b) -> ParsecT s u m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Either [Char] (GTIN n) -> ParsecT s u m (GTIN n)
forall s (m :: * -> *) a.
(Show s, MonadFail m) =>
Either s a -> m a
_liftEither (Either [Char] (GTIN n) -> ParsecT s u m (GTIN n))
-> (GTIN n -> Either [Char] (GTIN n))
-> GTIN n
-> ParsecT s u m (GTIN n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GTIN n -> Either [Char] (GTIN n)
forall a. Validity a => a -> Either [Char] a
prettyValidate

-- | A parser for a gtin number with an arbitrary number of digits between two and nineteen. the parser forces the stream to /end/ after the gtin,
-- but does /not/ validate if the gtin is indeed valid. The parser parses the number of digits with an arbitrary number of spaces between any two digits.
gtinParser' ::
  forall s u m n.
  ((TN.<=) 2 n, (TN.<=) n 19, KnownNat n, Stream s m Char) =>
  -- | A parser parsing a GTIN with an arbitrary number of digits thats force the stream to end, but does /not/ check the checksum.
  ParsecT s u m (GTIN n)
gtinParser' :: forall s u (m :: * -> *) (n :: Natural).
(2 <= n, n <= 19, KnownNat n, Stream s m Char) =>
ParsecT s u m (GTIN n)
gtinParser' = ParsecT s u m (GTIN n)
forall s u (m :: * -> *) (n :: Natural).
(2 <= n, n <= 19, KnownNat n, Stream s m Char) =>
ParsecT s u m (GTIN n)
gtinParser_' ParsecT s u m (GTIN n)
-> ParsecT s u m () -> ParsecT s u m (GTIN n)
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT s u m ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof

-- | A parser for a gtin number with an arbitrary number of digits between two and nineteen. the parser forces the stream to /end/ after the gtin,
-- and validates if the gtin is indeed valid. The parser parses the number of digits with an arbitrary number of spaces between any two digits.
gtinParser ::
  forall s u m n.
  ((TN.<=) 2 n, (TN.<=) n 19, KnownNat n, Stream s m Char) =>
  -- | A parser parsing a GTIN with an arbitrary number of digits that forces the stream to end, and does checks the checksum.
  ParsecT s u m (GTIN n)
gtinParser :: forall s u (m :: * -> *) (n :: Natural).
(2 <= n, n <= 19, KnownNat n, Stream s m Char) =>
ParsecT s u m (GTIN n)
gtinParser = ParsecT s u m (GTIN n)
forall s u (m :: * -> *) (n :: Natural).
(2 <= n, n <= 19, KnownNat n, Stream s m Char) =>
ParsecT s u m (GTIN n)
gtinParser_ ParsecT s u m (GTIN n)
-> ParsecT s u m () -> ParsecT s u m (GTIN n)
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT s u m ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof

-- | Run the 'gtinParser_'' parser and thus parses a 'GTIN' with an arbitrary number of digits. The parser does not require the stream to end after the 'GTIN', and does /not/ validate the checksum.
parseGTIN_' ::
  forall n s.
  ((TN.<=) 2 n, (TN.<=) n 19, KnownNat n, Stream s Identity Char) =>
  -- | The stream to parse.
  s ->
  -- | The result of the parser: 'Either' a 'ParseError' or the parsed 'GTIN'.
  Either ParseError (GTIN n)
parseGTIN_' :: forall (n :: Natural) s.
(2 <= n, n <= 19, KnownNat n, Stream s Identity Char) =>
s -> Either ParseError (GTIN n)
parseGTIN_' = Parsec s () (GTIN n)
-> () -> [Char] -> s -> Either ParseError (GTIN n)
forall s t u a.
Stream s Identity t =>
Parsec s u a -> u -> [Char] -> s -> Either ParseError a
runParser Parsec s () (GTIN n)
forall s u (m :: * -> *) (n :: Natural).
(2 <= n, n <= 19, KnownNat n, Stream s m Char) =>
ParsecT s u m (GTIN n)
gtinParser_' () [Char]
""

-- | Run the 'gtinParser_'' parser and thus parses a 'GTIN' with an arbitrary number of digits. The parser requires the stream to end after the 'GTIN', but does /not/ validate the checksum.
parseGTIN' ::
  forall n s.
  ((TN.<=) 2 n, (TN.<=) n 19, KnownNat n, Stream s Identity Char) =>
  -- | The stream to parse.
  s ->
  -- | The result of the parser: 'Either' a 'ParseError' or the parsed 'GTIN'.
  Either ParseError (GTIN n)
parseGTIN' :: forall (n :: Natural) s.
(2 <= n, n <= 19, KnownNat n, Stream s Identity Char) =>
s -> Either ParseError (GTIN n)
parseGTIN' = Parsec s () (GTIN n)
-> () -> [Char] -> s -> Either ParseError (GTIN n)
forall s t u a.
Stream s Identity t =>
Parsec s u a -> u -> [Char] -> s -> Either ParseError a
runParser Parsec s () (GTIN n)
forall s u (m :: * -> *) (n :: Natural).
(2 <= n, n <= 19, KnownNat n, Stream s m Char) =>
ParsecT s u m (GTIN n)
gtinParser' () [Char]
""

-- | Run the 'gtinParser_'' parser and thus parses a 'GTIN' with an arbitrary number of digits. The parser does not require the stream to end after the 'GTIN', but validates the checksum.
parseGTIN_ ::
  forall n s.
  ((TN.<=) 2 n, (TN.<=) n 19, KnownNat n, Stream s Identity Char) =>
  -- | The stream to parse.
  s ->
  -- | The result of the parser: 'Either' a 'ParseError' or the parsed 'GTIN'.
  Either ParseError (GTIN n)
parseGTIN_ :: forall (n :: Natural) s.
(2 <= n, n <= 19, KnownNat n, Stream s Identity Char) =>
s -> Either ParseError (GTIN n)
parseGTIN_ = Parsec s () (GTIN n)
-> () -> [Char] -> s -> Either ParseError (GTIN n)
forall s t u a.
Stream s Identity t =>
Parsec s u a -> u -> [Char] -> s -> Either ParseError a
runParser Parsec s () (GTIN n)
forall s u (m :: * -> *) (n :: Natural).
(2 <= n, n <= 19, KnownNat n, Stream s m Char) =>
ParsecT s u m (GTIN n)
gtinParser_ () [Char]
""

-- | Run the 'gtinParser_'' parser and thus parses a 'GTIN' with an arbitrary number of digits. The parser requires the stream to end after the 'GTIN', and validates the checksum.
parseGTIN ::
  forall n s.
  ((TN.<=) 2 n, (TN.<=) n 19, KnownNat n, Stream s Identity Char) =>
  -- | The stream to parse.
  s ->
  -- | The result of the parser: 'Either' a 'ParseError' or the parsed 'GTIN'.
  Either ParseError (GTIN n)
parseGTIN :: forall (n :: Natural) s.
(2 <= n, n <= 19, KnownNat n, Stream s Identity Char) =>
s -> Either ParseError (GTIN n)
parseGTIN = Parsec s () (GTIN n)
-> () -> [Char] -> s -> Either ParseError (GTIN n)
forall s t u a.
Stream s Identity t =>
Parsec s u a -> u -> [Char] -> s -> Either ParseError a
runParser Parsec s () (GTIN n)
forall s u (m :: * -> *) (n :: Natural).
(2 <= n, n <= 19, KnownNat n, Stream s m Char) =>
ParsecT s u m (GTIN n)
gtinParser () [Char]
""

-- | A function that constructs a 'GTIN' expression or pattern based on a given string. The 'Proxy' parameter is used to specify the number of digits of the 'GTIN' number.
gtinQ ::
  forall n.
  ((TN.<=) 2 n, (TN.<=) n 19, KnownNat n) =>
  -- | The 'Proxy' object that is ignored, but used to determine the number of digits of the 'GTIN' number.
  Proxy (GTIN n) ->
  -- | The corresponding 'QuasiQuoter' that resolves to a 'GTIN' expression or pattern.
  QuasiQuoter
gtinQ :: forall (n :: Natural).
(2 <= n, n <= 19, KnownNat n) =>
Proxy (GTIN n) -> QuasiQuoter
gtinQ Proxy (GTIN n)
_ =
  QuasiQuoter
    { quoteExp :: [Char] -> Q Exp
quoteExp = (Either ParseError (GTIN n) -> Q (GTIN n)
forall s (m :: * -> *) a.
(Show s, MonadFail m) =>
Either s a -> m a
_liftEither (Either ParseError (GTIN n) -> Q (GTIN n))
-> (GTIN n -> Q Exp) -> Either ParseError (GTIN n) -> Q Exp
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> GTIN n -> Q Exp
forall t (m :: * -> *). (Lift t, Quote m) => t -> m Exp
forall (m :: * -> *). Quote m => GTIN n -> m Exp
lift) (Either ParseError (GTIN n) -> Q Exp)
-> ([Char] -> Either ParseError (GTIN n)) -> [Char] -> Q Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Natural) s.
(2 <= n, n <= 19, KnownNat n, Stream s Identity Char) =>
s -> Either ParseError (GTIN n)
parseGTIN @n,
      quotePat :: [Char] -> Q Pat
quotePat = (Either ParseError (GTIN n) -> Q (GTIN n)
forall s (m :: * -> *) a.
(Show s, MonadFail m) =>
Either s a -> m a
_liftEither (Either ParseError (GTIN n) -> Q (GTIN n))
-> (GTIN n -> Q Pat) -> Either ParseError (GTIN n) -> Q Pat
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Pat -> Q Pat
forall a. a -> Q a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Pat -> Q Pat) -> (GTIN n -> Pat) -> GTIN n -> Q Pat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GTIN n -> Pat
forall (n :: Natural). GTIN n -> Pat
_toPattern) (Either ParseError (GTIN n) -> Q Pat)
-> ([Char] -> Either ParseError (GTIN n)) -> [Char] -> Q Pat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Natural) s.
(2 <= n, n <= 19, KnownNat n, Stream s Identity Char) =>
s -> Either ParseError (GTIN n)
parseGTIN @n,
      quoteType :: [Char] -> Q Type
quoteType = Q Type -> [Char] -> Q Type
forall a b. a -> b -> a
const ([Char] -> Q Type
forall a. [Char] -> Q a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail [Char]
"can not produce a type with this QuasiQuoter"),
      quoteDec :: [Char] -> Q [Dec]
quoteDec = Q [Dec] -> [Char] -> Q [Dec]
forall a b. a -> b -> a
const ([Char] -> Q [Dec]
forall a. [Char] -> Q a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail [Char]
"can not produce a declaration with this QuasiQuoter")
    }

-- | A 'QuasiQuoter' for an 'SSCC' number.
ssccQ ::
  -- | The corresponding 'QuasiQuoter'.
  QuasiQuoter
ssccQ :: QuasiQuoter
ssccQ = forall (n :: Natural).
(2 <= n, n <= 19, KnownNat n) =>
Proxy (GTIN n) -> QuasiQuoter
gtinQ @18 Proxy (GTIN 18)
forall {k} (t :: k). Proxy t
Proxy

-- | A 'QuasiQuoter' for a 'GSIN' number.
gsinQ ::
  -- | The corresponding 'QuasiQuoter'.
  QuasiQuoter
gsinQ :: QuasiQuoter
gsinQ = forall (n :: Natural).
(2 <= n, n <= 19, KnownNat n) =>
Proxy (GTIN n) -> QuasiQuoter
gtinQ @17 Proxy (GTIN 17)
forall {k} (t :: k). Proxy t
Proxy

-- | A 'QuasiQuoter' for an 'GTIN14' number.
gtin14Q ::
  -- | The corresponding 'QuasiQuoter'.
  QuasiQuoter
gtin14Q :: QuasiQuoter
gtin14Q = forall (n :: Natural).
(2 <= n, n <= 19, KnownNat n) =>
Proxy (GTIN n) -> QuasiQuoter
gtinQ @14 Proxy (GTIN 14)
forall {k} (t :: k). Proxy t
Proxy

-- | A 'QuasiQuoter' for an 'EANUCC14' number.
eanucc14Q ::
  -- | The corresponding 'QuasiQuoter'.
  QuasiQuoter
eanucc14Q :: QuasiQuoter
eanucc14Q = QuasiQuoter
gtin14Q

-- | A 'QuasiQuoter' for an 'SCC14' number.
scc14Q ::
  -- | The corresponding 'QuasiQuoter'.
  QuasiQuoter
scc14Q :: QuasiQuoter
scc14Q = QuasiQuoter
gtin14Q

-- | A 'QuasiQuoter' for an 'GTIN13' number.
gtin13Q ::
  -- | The corresponding 'QuasiQuoter'.
  QuasiQuoter
gtin13Q :: QuasiQuoter
gtin13Q = forall (n :: Natural).
(2 <= n, n <= 19, KnownNat n) =>
Proxy (GTIN n) -> QuasiQuoter
gtinQ @13 Proxy ISBN13
forall {k} (t :: k). Proxy t
Proxy

-- | A 'QuasiQuoter' for an 'EAN' number.
eanQ ::
  -- | The corresponding 'QuasiQuoter'.
  QuasiQuoter
eanQ :: QuasiQuoter
eanQ = QuasiQuoter
gtin13Q

-- | A 'QuasiQuoter' for an 'EANUCC13' number.
eanucc13Q ::
  -- | The corresponding 'QuasiQuoter'.
  QuasiQuoter
eanucc13Q :: QuasiQuoter
eanucc13Q = QuasiQuoter
gtin13Q

-- | A 'QuasiQuoter' for an 'GTIN12' number.
gtin12Q ::
  -- | The corresponding 'QuasiQuoter'.
  QuasiQuoter
gtin12Q :: QuasiQuoter
gtin12Q = forall (n :: Natural).
(2 <= n, n <= 19, KnownNat n) =>
Proxy (GTIN n) -> QuasiQuoter
gtinQ @12 Proxy (GTIN 12)
forall {k} (t :: k). Proxy t
Proxy

-- | A 'QuasiQuoter' for an 'GTIN8' number.
gtin8Q ::
  -- | The corresponding 'QuasiQuoter'.
  QuasiQuoter
gtin8Q :: QuasiQuoter
gtin8Q = forall (n :: Natural).
(2 <= n, n <= 19, KnownNat n) =>
Proxy (GTIN n) -> QuasiQuoter
gtinQ @8 Proxy (GTIN 8)
forall {k} (t :: k). Proxy t
Proxy

-- | A 'QuasiQuoter' for an 'EANUCC8' number.
eanucc8Q ::
  -- | The corresponding 'QuasiQuoter'.
  QuasiQuoter
eanucc8Q :: QuasiQuoter
eanucc8Q = QuasiQuoter
gtin8Q

-- | A 'QuasiQuoter' for an 'ISBN13' number.
isbn13Q ::
  -- | The corresponding 'QuasiQuoter'.
  QuasiQuoter
isbn13Q :: QuasiQuoter
isbn13Q = forall (n :: Natural).
(2 <= n, n <= 19, KnownNat n) =>
Proxy (GTIN n) -> QuasiQuoter
gtinQ @13 Proxy ISBN13
forall {k} (t :: k). Proxy t
Proxy

-- | A 'QuasiQuoter' for an 'ISBN' number, only the thirteen digit number is supported.
isbnQ ::
  -- | The corresponding 'QuasiQuoter'.
  QuasiQuoter
isbnQ :: QuasiQuoter
isbnQ = QuasiQuoter
isbn13Q