module Text.LDIF.Types (
LDIF(..),
LDIFRecord(..),
Change(..),
Modify(..),
DN(..),
LDIFType(..),
Attribute(..), Value(..), AttrValue,
isContentRecord,
isChangeRecord,
getLDIFType
)
where
import qualified Data.ByteString.Char8 as BC
import Data.Char
data Attribute = Attribute { aName :: BC.ByteString } deriving Show
instance Eq Attribute where
(Attribute xs) == (Attribute ys) = (BC.map toUpper xs) == (BC.map toUpper ys)
instance Ord Attribute where
(Attribute xs) `compare` (Attribute ys) = (BC.map toUpper xs) `compare` (BC.map toUpper ys)
data Value = Value { aVal :: BC.ByteString }
| ValueI { aVal :: BC.ByteString } deriving Show
instance Eq Value where
(Value xs) == (Value ys) = xs == ys
xs == ys = (BC.map toUpper $ aVal xs) == (BC.map toUpper $ aVal ys)
instance Ord Value where
(Value xs) `compare` (Value ys) = xs `compare` ys
xs `compare` ys = (BC.map toUpper $ aVal xs) `compare` (BC.map toUpper $ aVal ys)
type AttrValue = (Attribute, Value)
data LDIFType = LDIFContentType
| LDIFChangesType
| LDIFMixedType
deriving Eq
instance Show LDIFType where
show LDIFChangesType = "Delta"
show LDIFContentType = "Content"
show LDIFMixedType = "Mixed"
data LDIF = LDIF { lcVersion :: Maybe BC.ByteString, lcEntries :: ![LDIFRecord] } deriving (Show, Eq)
data LDIFRecord
= ContentRecord { reDN :: !DN, coAttrVals :: ![AttrValue] }
| ChangeRecord { reDN :: !DN, chOp :: !Change } deriving (Show, Eq)
data Change = ChangeAdd { chAttrVals :: ![AttrValue] }
| ChangeDelete
| ChangeModify { chMods :: ![Modify] }
| ChangeModDN deriving (Show, Eq)
data Modify = ModAdd { modAttr :: !Attribute, modAttrVals :: ![Value] }
| ModDelete { modAttr :: !Attribute, modAttrVals :: ![Value] }
| ModReplace { modAttr :: !Attribute, modAttrVals :: ![Value] } deriving (Show, Eq)
data DN = DN { dnAttrVals :: ![AttrValue] } deriving (Eq, Show)
instance Ord DN where
(DN xs1) `compare` (DN xs2) = let cmpAV ((a1,v1),(a2,v2)) = let ca = a1 `compare` a2
cv = v1 `compare` v2
in if ca == EQ then cv else ca
dx = map cmpAV $ zip (reverse $ xs1) (reverse $ xs2)
lx | length xs1 > length xs2 = GT
| length xs1 < length xs2 = LT
| otherwise = EQ
in case filter (EQ /=) dx of
[] -> lx
(x:_) -> x
isContentRecord :: LDIFRecord -> Bool
isContentRecord (ContentRecord _ _) = True
isContentRecord _ = False
isChangeRecord :: LDIFRecord -> Bool
isChangeRecord (ChangeRecord _ _) = True
isChangeRecord _ = False
getLDIFType :: LDIF -> LDIFType
getLDIFType (LDIF _ []) = LDIFContentType
getLDIFType (LDIF _ xs) = getLDIFType' con chg
where
con = filter (isContentRecord) xs
chg = filter (not . isContentRecord) xs
getLDIFType' [] [] = LDIFContentType
getLDIFType' [] _ = LDIFChangesType
getLDIFType' _ [] = LDIFContentType
getLDIFType' _ _ = LDIFMixedType