    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE DeriveGeneric #-}
    module Distribution.SPDX.LicenseReference (
        LicenseRef,
        licenseRef,
        licenseDocumentRef,
        mkLicenseRef,
        mkLicenseRef',
        ) where

    import Prelude ()
    import Distribution.Compat.Prelude

    import Distribution.Utils.Generic (isAsciiAlphaNum)
    import Distribution.Pretty
    import Distribution.Parsec

    import qualified Distribution.Compat.CharParsing as P
    import qualified Text.PrettyPrint as Disp

    -- | A user defined license reference denoted by @LicenseRef-[idstring]@ (for a license not on the SPDX License List);
    data LicenseRef = LicenseRef
        { LicenseRef -> Maybe String
    _lrDocument :: !(Maybe String)
        , LicenseRef -> String
    _lrLicense  :: !String
        }
      deriving (Int -> LicenseRef -> ShowS
    [LicenseRef] -> ShowS
    LicenseRef -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [LicenseRef] -> ShowS
    $cshowList :: [LicenseRef] -> ShowS
    show :: LicenseRef -> String
    $cshow :: LicenseRef -> String
    showsPrec :: Int -> LicenseRef -> ShowS
    $cshowsPrec :: Int -> LicenseRef -> ShowS
    Show, ReadPrec [LicenseRef]
    ReadPrec LicenseRef
    Int -> ReadS LicenseRef
    ReadS [LicenseRef]
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [LicenseRef]
    $creadListPrec :: ReadPrec [LicenseRef]
    readPrec :: ReadPrec LicenseRef
    $creadPrec :: ReadPrec LicenseRef
    readList :: ReadS [LicenseRef]
    $creadList :: ReadS [LicenseRef]
    readsPrec :: Int -> ReadS LicenseRef
    $creadsPrec :: Int -> ReadS LicenseRef
    Read, LicenseRef -> LicenseRef -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: LicenseRef -> LicenseRef -> Bool
    $c/= :: LicenseRef -> LicenseRef -> Bool
    == :: LicenseRef -> LicenseRef -> Bool
    $c== :: LicenseRef -> LicenseRef -> Bool
    Eq, Eq LicenseRef
    LicenseRef -> LicenseRef -> Bool
    LicenseRef -> LicenseRef -> Ordering
    LicenseRef -> LicenseRef -> LicenseRef
    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
    min :: LicenseRef -> LicenseRef -> LicenseRef
    $cmin :: LicenseRef -> LicenseRef -> LicenseRef
    max :: LicenseRef -> LicenseRef -> LicenseRef
    $cmax :: LicenseRef -> LicenseRef -> LicenseRef
    >= :: LicenseRef -> LicenseRef -> Bool
    $c>= :: LicenseRef -> LicenseRef -> Bool
    > :: LicenseRef -> LicenseRef -> Bool
    $c> :: LicenseRef -> LicenseRef -> Bool
    <= :: LicenseRef -> LicenseRef -> Bool
    $c<= :: LicenseRef -> LicenseRef -> Bool
    < :: LicenseRef -> LicenseRef -> Bool
    $c< :: LicenseRef -> LicenseRef -> Bool
    compare :: LicenseRef -> LicenseRef -> Ordering
    $ccompare :: LicenseRef -> LicenseRef -> Ordering
    Ord, Typeable, Typeable LicenseRef
    LicenseRef -> DataType
    LicenseRef -> Constr
    (forall b. Data b => b -> b) -> LicenseRef -> LicenseRef
    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) -> LicenseRef -> u
    forall u. (forall d. Data d => d -> u) -> LicenseRef -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> LicenseRef -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> LicenseRef -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> LicenseRef -> m LicenseRef
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> LicenseRef -> m LicenseRef
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c LicenseRef
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> LicenseRef -> c LicenseRef
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c LicenseRef)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c LicenseRef)
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> LicenseRef -> m LicenseRef
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> LicenseRef -> m LicenseRef
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> LicenseRef -> m LicenseRef
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> LicenseRef -> m LicenseRef
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> LicenseRef -> m LicenseRef
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> LicenseRef -> m LicenseRef
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> LicenseRef -> u
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> LicenseRef -> u
    gmapQ :: forall u. (forall d. Data d => d -> u) -> LicenseRef -> [u]
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> LicenseRef -> [u]
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> LicenseRef -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> LicenseRef -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> LicenseRef -> r
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> LicenseRef -> r
    gmapT :: (forall b. Data b => b -> b) -> LicenseRef -> LicenseRef
    $cgmapT :: (forall b. Data b => b -> b) -> LicenseRef -> LicenseRef
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c LicenseRef)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c LicenseRef)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c LicenseRef)
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c LicenseRef)
    dataTypeOf :: LicenseRef -> DataType
    $cdataTypeOf :: LicenseRef -> DataType
    toConstr :: LicenseRef -> Constr
    $ctoConstr :: LicenseRef -> Constr
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c LicenseRef
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c LicenseRef
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> LicenseRef -> c LicenseRef
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> LicenseRef -> c LicenseRef
    Data, forall x. Rep LicenseRef x -> LicenseRef
    forall x. LicenseRef -> Rep LicenseRef x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cto :: forall x. Rep LicenseRef x -> LicenseRef
    $cfrom :: forall x. LicenseRef -> Rep LicenseRef x
    Generic)

    -- | License reference.
    licenseRef :: LicenseRef -> String
    licenseRef :: LicenseRef -> String
    licenseRef = LicenseRef -> String
    _lrLicense

    -- | Document reference.
    licenseDocumentRef :: LicenseRef -> Maybe String
    licenseDocumentRef :: LicenseRef -> Maybe String
    licenseDocumentRef = LicenseRef -> Maybe String
    _lrDocument

    instance Binary LicenseRef
    instance Structured LicenseRef

    instance NFData LicenseRef where
        rnf :: LicenseRef -> ()
    rnf (LicenseRef Maybe String
    d String
    l) = forall a. NFData a => a -> ()
    rnf Maybe String
    d seq :: forall a b. a -> b -> b
    `seq` forall a. NFData a => a -> ()
    rnf String
    l

    instance Pretty LicenseRef where
        pretty :: LicenseRef -> Doc
    pretty (LicenseRef Maybe String
    Nothing String
    l) = String -> Doc
    Disp.text String
    "LicenseRef-" Doc -> Doc -> Doc
    <<>> String -> Doc
    Disp.text String
    l
        pretty (LicenseRef (Just String
    d) String
    l) =
            String -> Doc
    Disp.text String
    "DocumentRef-" Doc -> Doc -> Doc
    <<>> String -> Doc
    Disp.text String
    d Doc -> Doc -> Doc
    <<>> Char -> Doc
    Disp.char Char
    ':' Doc -> Doc -> Doc
    <<>> String -> Doc
    Disp.text String
    "LicenseRef-" Doc -> Doc -> Doc
    <<>> String -> Doc
    Disp.text String
    l

    instance Parsec LicenseRef where
        parsec :: forall (m :: * -> *). CabalParsing m => m LicenseRef
    parsec = m LicenseRef
    name forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> m LicenseRef
    doc
          where
            name :: m LicenseRef
    name = do
                String
    _ <- forall (m :: * -> *). CharParsing m => String -> m String
    P.string String
    "LicenseRef-"
                String
    n <- forall (f :: * -> *) a. Alternative f => f a -> f [a]
    some forall a b. (a -> b) -> a -> b
    $ forall (m :: * -> *). CharParsing m => (Char -> Bool) -> m Char
    P.satisfy forall a b. (a -> b) -> a -> b
    $ \Char
    c -> Char -> Bool
    isAsciiAlphaNum Char
    c Bool -> Bool -> Bool
    || Char
    c forall a. Eq a => a -> a -> Bool
    == Char
    '-' Bool -> Bool -> Bool
    || Char
    c forall a. Eq a => a -> a -> Bool
    == Char
    '.'
                forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Maybe String -> String -> LicenseRef
    LicenseRef forall a. Maybe a
    Nothing String
    n)

            doc :: m LicenseRef
    doc = do
                String
    _ <- forall (m :: * -> *). CharParsing m => String -> m String
    P.string String
    "DocumentRef-"
                String
    d <- forall (f :: * -> *) a. Alternative f => f a -> f [a]
    some forall a b. (a -> b) -> a -> b
    $ forall (m :: * -> *). CharParsing m => (Char -> Bool) -> m Char
    P.satisfy forall a b. (a -> b) -> a -> b
    $ \Char
    c -> Char -> Bool
    isAsciiAlphaNum Char
    c Bool -> Bool -> Bool
    || Char
    c forall a. Eq a => a -> a -> Bool
    == Char
    '-' Bool -> Bool -> Bool
    || Char
    c forall a. Eq a => a -> a -> Bool
    == Char
    '.'
                Char
    _ <- forall (m :: * -> *). CharParsing m => Char -> m Char
    P.char Char
    ':'
                String
    _ <- forall (m :: * -> *). CharParsing m => String -> m String
    P.string String
    "LicenseRef-"
                String
    n <- forall (f :: * -> *) a. Alternative f => f a -> f [a]
    some forall a b. (a -> b) -> a -> b
    $ forall (m :: * -> *). CharParsing m => (Char -> Bool) -> m Char
    P.satisfy forall a b. (a -> b) -> a -> b
    $ \Char
    c -> Char -> Bool
    isAsciiAlphaNum Char
    c Bool -> Bool -> Bool
    || Char
    c forall a. Eq a => a -> a -> Bool
    == Char
    '-' Bool -> Bool -> Bool
    || Char
    c forall a. Eq a => a -> a -> Bool
    == Char
    '.'
                forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Maybe String -> String -> LicenseRef
    LicenseRef (forall a. a -> Maybe a
    Just String
    d) String
    n)

    -- | Create 'LicenseRef' from optional document ref and name.
    mkLicenseRef :: Maybe String -> String -> Maybe LicenseRef
    mkLicenseRef :: Maybe String -> String -> Maybe LicenseRef
    mkLicenseRef Maybe String
    d String
    l = do
        Maybe String
    d' <- forall (t :: * -> *) (f :: * -> *) a b.
    (Traversable t, Applicative f) =>
    (a -> f b) -> t a -> f (t b)
    traverse forall {t :: * -> *}. Foldable t => t Char -> Maybe (t Char)
    checkIdString Maybe String
    d
        String
    l' <- forall {t :: * -> *}. Foldable t => t Char -> Maybe (t Char)
    checkIdString String
    l
        forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Maybe String -> String -> LicenseRef
    LicenseRef Maybe String
    d' String
    l')
      where
        checkIdString :: t Char -> Maybe (t Char)
    checkIdString t Char
    s
            | forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all (\Char
    c -> Char -> Bool
    isAsciiAlphaNum Char
    c Bool -> Bool -> Bool
    || Char
    c forall a. Eq a => a -> a -> Bool
    == Char
    '-' Bool -> Bool -> Bool
    || Char
    c forall a. Eq a => a -> a -> Bool
    == Char
    '.') t Char
    s = forall a. a -> Maybe a
    Just t Char
    s
            | Bool
    otherwise = forall a. Maybe a
    Nothing

    -- | Like 'mkLicenseRef' but convert invalid characters into @-@.
    mkLicenseRef' :: Maybe String -> String -> LicenseRef
    mkLicenseRef' :: Maybe String -> String -> LicenseRef
    mkLicenseRef' Maybe String
    d String
    l = Maybe String -> String -> LicenseRef
    LicenseRef (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ShowS
    f Maybe String
    d) (ShowS
    f String
    l)
      where
        f :: ShowS
    f = forall a b. (a -> b) -> [a] -> [b]
    map Char -> Char
    g
        g :: Char -> Char
    g Char
    c | Char -> Bool
    isAsciiAlphaNum Char
    c Bool -> Bool -> Bool
    || Char
    c forall a. Eq a => a -> a -> Bool
    == Char
    '-' Bool -> Bool -> Bool
    || Char
    c forall a. Eq a => a -> a -> Bool
    == Char
    '.' = Char
    c
            | Bool
    otherwise                                 = Char
    '-'