{-# 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.Class 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 { _lrDocument :: !(Maybe String) , _lrLicense :: !String } deriving (Show, Read, Eq, Ord, Typeable, Data, Generic) -- | License reference. licenseRef :: LicenseRef -> String licenseRef = _lrLicense -- | Document reference. licenseDocumentRef :: LicenseRef -> Maybe String licenseDocumentRef = _lrDocument instance Binary LicenseRef instance NFData LicenseRef where rnf (LicenseRef d l) = rnf d `seq` rnf l instance Pretty LicenseRef where pretty (LicenseRef Nothing l) = Disp.text "LicenseRef-" <<>> Disp.text l pretty (LicenseRef (Just d) l) = Disp.text "DocumentRef-" <<>> Disp.text d <<>> Disp.char ':' <<>> Disp.text "LicenseRef-" <<>> Disp.text l instance Parsec LicenseRef where parsec = name <|> doc where name = do _ <- P.string "LicenseRef-" n <- some $ P.satisfy $ \c -> isAsciiAlphaNum c || c == '-' || c == '.' pure (LicenseRef Nothing n) doc = do _ <- P.string "DocumentRef-" d <- some $ P.satisfy $ \c -> isAsciiAlphaNum c || c == '-' || c == '.' _ <- P.char ':' _ <- P.string "LicenseRef-" n <- some $ P.satisfy $ \c -> isAsciiAlphaNum c || c == '-' || c == '.' pure (LicenseRef (Just d) n) -- | Create 'LicenseRef' from optional document ref and name. mkLicenseRef :: Maybe String -> String -> Maybe LicenseRef mkLicenseRef d l = do d' <- traverse checkIdString d l' <- checkIdString l pure (LicenseRef d' l') where checkIdString s | all (\c -> isAsciiAlphaNum c || c == '-' || c == '.') s = Just s | otherwise = Nothing -- | Like 'mkLicenseRef' but convert invalid characters into @-@. mkLicenseRef' :: Maybe String -> String -> LicenseRef mkLicenseRef' d l = LicenseRef (fmap f d) (f l) where f = map g g c | isAsciiAlphaNum c || c == '-' || c == '.' = c | otherwise = '-'