-- 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.

-- | An NV type contains the name and version of a package only.
module Data.RPM.NV (
  NV(..),
  showNV,
  readNV,
  eitherNV,
  maybeNV
  )
where

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

-- | Package name-version type
data NV = NV {NV -> String
name :: String,
              NV -> String
version :: String}
  deriving (NV -> NV -> Bool
(NV -> NV -> Bool) -> (NV -> NV -> Bool) -> Eq NV
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NV -> NV -> Bool
$c/= :: NV -> NV -> Bool
== :: NV -> NV -> Bool
$c== :: NV -> NV -> Bool
Eq)

-- | Render an name-version
showNV :: NV -> String
showNV :: NV -> String
showNV (NV nm :: String
nm ver :: String
ver) = String
nm String -> String -> String
forall a. [a] -> [a] -> [a]
++ "-" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
ver

-- | Read a package name-version or return a failure string
eitherNV :: String -> Either String NV
eitherNV :: String -> Either String NV
eitherNV "" = String -> Either String NV
forall a b. a -> Either a b
Left "NV cannot be empty string"
eitherNV s :: String
s =
  case String -> String -> Maybe (String, String)
forall a. Eq a => [a] -> [a] -> Maybe ([a], [a])
stripInfixEnd "-" String
s of
    Just (n :: String
n,v :: String
v) ->
      if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
n Bool -> Bool -> Bool
|| String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
v
      then String -> Either String NV
forall a b. a -> Either a b
Left (String -> Either String NV) -> String -> Either String NV
forall a b. (a -> b) -> a -> b
$ "NV must not start or end with '-': " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s
      else NV -> Either String NV
forall a b. b -> Either a b
Right (String -> String -> NV
NV String
n String
v)
    Nothing -> String -> Either String NV
forall a b. a -> Either a b
Left (String -> Either String NV) -> String -> Either String NV
forall a b. (a -> b) -> a -> b
$ "NV must contain '-': " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s

-- | Maybe read an package name-version
maybeNV :: String -> Maybe NV
maybeNV :: String -> Maybe NV
maybeNV = Either String NV -> Maybe NV
forall a b. Either a b -> Maybe b
eitherToMaybe (Either String NV -> Maybe NV)
-> (String -> Either String NV) -> String -> Maybe NV
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Either String NV
eitherNV

-- | Read an NV
--
-- Errors if not of the form "name-version"
readNV :: String -> NV
readNV :: String -> NV
readNV =  (String -> NV) -> (NV -> NV) -> Either String NV -> NV
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> NV
forall a. HasCallStack => String -> a
error NV -> NV
forall a. a -> a
id (Either String NV -> NV)
-> (String -> Either String NV) -> String -> NV
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Either String NV
eitherNV