-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 2 of the License, or
-- (at your option) any later version.

-- | A type for name-version-release of an RPM package
module Data.RPM.NVR (
  NVR(..),
  showNVR,
  readNVR,
  eitherNVR,
  maybeNVR,
  VerRel(..),
  )
where

import Data.Either.Extra
import Data.List.Extra

import Data.RPM.VerRel

-- | An rpm package name-version-release
data NVR = NVR String VerRel
  deriving NVR -> NVR -> Bool
(NVR -> NVR -> Bool) -> (NVR -> NVR -> Bool) -> Eq NVR
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NVR -> NVR -> Bool
$c/= :: NVR -> NVR -> Bool
== :: NVR -> NVR -> Bool
$c== :: NVR -> NVR -> Bool
Eq

-- | render an name-version-release
showNVR :: NVR -> String
showNVR :: NVR -> String
showNVR (NVR nm :: String
nm verrel :: VerRel
verrel) = String
nm String -> String -> String
forall a. [a] -> [a] -> [a]
++ "-" String -> String -> String
forall a. [a] -> [a] -> [a]
++ VerRel -> String
showVerRel VerRel
verrel

-- | Either read a package name-version-release or return a failure string
eitherNVR :: String -> Either String NVR
eitherNVR :: String -> Either String NVR
eitherNVR s :: String
s =
  case [String] -> [String]
forall a. [a] -> [a]
reverse (String -> String -> [String]
forall a. (Partial, Eq a) => [a] -> [a] -> [[a]]
splitOn "-" String
s) of
    rel :: String
rel:ver :: String
ver:emaN :: [String]
emaN ->
      if (String -> Bool) -> [String] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (String
relString -> [String] -> [String]
forall a. a -> [a] -> [a]
:String
verString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
emaN)
      then String -> Either String NVR
forall a b. a -> Either a b
Left (String -> Either String NVR) -> String -> Either String NVR
forall a b. (a -> b) -> a -> b
$ "NVR cannot start or end with '-'s: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s
      else NVR -> Either String NVR
forall a b. b -> Either a b
Right (String -> VerRel -> NVR
NVR (String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate "-" ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ [String] -> [String]
forall a. [a] -> [a]
reverse [String]
emaN) (String -> String -> VerRel
VerRel String
ver String
rel))
    _ ->
      String -> Either String NVR
forall a b. a -> Either a b
Left (String -> Either String NVR) -> String -> Either String NVR
forall a b. (a -> b) -> a -> b
$ "malformed NVR string: '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ "'"

-- | Maybe read a package name-version-release string
maybeNVR :: String -> Maybe NVR
maybeNVR :: String -> Maybe NVR
maybeNVR = Either String NVR -> Maybe NVR
forall a b. Either a b -> Maybe b
eitherToMaybe (Either String NVR -> Maybe NVR)
-> (String -> Either String NVR) -> String -> Maybe NVR
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Either String NVR
eitherNVR

-- | read an NVR
--
-- Errors if not of the form "name-version-release"
readNVR :: String -> NVR
readNVR :: String -> NVR
readNVR = (String -> NVR) -> (NVR -> NVR) -> Either String NVR -> NVR
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> NVR
forall a. Partial => String -> a
error NVR -> NVR
forall a. a -> a
id (Either String NVR -> NVR)
-> (String -> Either String NVR) -> String -> NVR
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Either String NVR
eitherNVR