-- 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 carrying the version and release of an rpm package.
module Data.RPM.VerRel (
  VerRel(..),
  showVerRel,
  readVerRel,
  eitherVerRel,
  maybeVerRel
  )
where

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

import Data.RPM.VerCmp

-- | The version-release of an (rpm) package, which is ordered by
-- @rpmVerCompare@ for version and release.
--
-- FIXME: note currently rpmVerCompare is not used for Eq (like codec-rpm).
data VerRel = VerRel {VerRel -> String
vrVersion :: String,
                      VerRel -> String
vrRelease :: String}
  deriving (VerRel -> VerRel -> Bool
(VerRel -> VerRel -> Bool)
-> (VerRel -> VerRel -> Bool) -> Eq VerRel
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: VerRel -> VerRel -> Bool
$c/= :: VerRel -> VerRel -> Bool
== :: VerRel -> VerRel -> Bool
$c== :: VerRel -> VerRel -> Bool
Eq)

-- | Display a VerRel
showVerRel :: VerRel -> String
showVerRel :: VerRel -> String
showVerRel (VerRel String
ver String
rel) = String
ver String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
rel

-- | Either read a package version-release or return an failure string
eitherVerRel :: String -> Either String VerRel
eitherVerRel :: String -> Either String VerRel
eitherVerRel String
s =
  case String -> String -> Maybe (String, String)
forall a. Eq a => [a] -> [a] -> Maybe ([a], [a])
stripInfixEnd String
"-" String
s of
    Just (String
v,String
r) ->
      if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
v Bool -> Bool -> Bool
|| String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
r
      then String -> Either String VerRel
forall a. HasCallStack => String -> a
error (String -> Either String VerRel) -> String -> Either String VerRel
forall a b. (a -> b) -> a -> b
$ String
"VerRel cannot start or end with '-': " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s
      else VerRel -> Either String VerRel
forall a b. b -> Either a b
Right (String -> String -> VerRel
VerRel String
v String
r)
    Maybe (String, String)
Nothing -> String -> Either String VerRel
forall a b. a -> Either a b
Left (String -> Either String VerRel) -> String -> Either String VerRel
forall a b. (a -> b) -> a -> b
$ String
"VerRel must contain a '-': " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s

-- | Maybe read a package version-release
maybeVerRel :: String -> Maybe VerRel
maybeVerRel :: String -> Maybe VerRel
maybeVerRel = Either String VerRel -> Maybe VerRel
forall a b. Either a b -> Maybe b
eitherToMaybe (Either String VerRel -> Maybe VerRel)
-> (String -> Either String VerRel) -> String -> Maybe VerRel
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Either String VerRel
eitherVerRel

-- | Read a version-release
--
-- Errors if malformed
readVerRel :: String -> VerRel
readVerRel :: String -> VerRel
readVerRel = (String -> VerRel)
-> (VerRel -> VerRel) -> Either String VerRel -> VerRel
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> VerRel
forall a. HasCallStack => String -> a
error VerRel -> VerRel
forall a. a -> a
id (Either String VerRel -> VerRel)
-> (String -> Either String VerRel) -> String -> VerRel
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Either String VerRel
eitherVerRel

instance Ord VerRel where
  compare :: VerRel -> VerRel -> Ordering
compare (VerRel String
v1 String
r1) (VerRel String
v2 String
r2) =
    case String -> String -> Ordering
rpmVerCompare String
v1 String
v2 of
      Ordering
EQ -> String -> String -> Ordering
rpmVerCompare String
r1 String
r2
      Ordering
o -> Ordering
o

-- appendRelease :: VerRel -> String -> VerRel
-- appendRelease (VerRel v r) d = VerRel v (r ++ d)