module Text.LDAP.Data
(
Attribute
, AttrType (..), attrOid
, AttrValue (..)
, Component (..), component
, DN, consDN, unconsDN
, List1
, LdifAttrValue (..)
,
DN', toDN', Component'
,
Bound, exact, boundsElems, inBounds, elem', notElem', inSBounds
, ordW8
, quotation, specialChars
, ldifSafeBounds
, ldifSafeInitBounds
) where
import Prelude hiding (reverse)
import Data.Ord (comparing)
import Data.List (sortBy)
import Data.Char (ord)
import Data.Word (Word8)
import Data.ByteString (ByteString)
import Data.Set (fromList, member)
import Data.List.NonEmpty (NonEmpty ((:|)), reverse, toList)
type List1 = NonEmpty
type Bound a = (a, a)
exact :: a -> Bound a
exact a = (a, a)
bexpand :: Enum a => (a, a) -> [a]
bexpand (x, y) = [x .. y]
boundsElems :: Enum a => [(a, a)] -> [a]
boundsElems = (>>= bexpand)
widerFirst :: (Enum a, Ord a) => [(a, a)] -> [(a, a)]
widerFirst = sortBy (flip $ comparing $ length . bexpand)
inBounds :: (Enum a, Ord a) => a -> [(a, a)] -> Bool
inBounds a = or . map (\(x, y) -> (x <= a && a <= y)) . widerFirst
elem' :: Ord a => a -> [a] -> Bool
elem' a = (a `member`) . fromList
notElem' :: Ord a => a -> [a] -> Bool
notElem' a = not . (a `elem'`)
inSBounds :: (Enum a, Ord a) => a -> [(a, a)] -> Bool
inSBounds a = (a `elem'`) . boundsElems
infix 4 `inBounds`, `elem'`, `notElem'`, `inSBounds`
data AttrType
= AttrType ByteString
| AttrOid (List1 ByteString)
deriving (Eq, Ord, Show)
attrOid :: ByteString -> [ByteString] -> AttrType
attrOid hd tl = AttrOid $ hd :| tl
newtype AttrValue = AttrValue ByteString
deriving (Eq, Ord, Show)
type Attribute = (AttrType, AttrValue)
data Component
= S Attribute
| L (List1 Attribute)
deriving (Eq, Ord, Show)
component :: Attribute -> [Attribute] -> Component
component = d where
d x [] = S x
d x xs@(_:_) = L $ x :| xs
type DN = List1 Component
consDN :: Component -> [Component] -> DN
consDN h tl = reverse $ h :| tl
unconsDN :: DN -> (Component, [Component])
unconsDN dn = (h, tl) where (h :| tl) = reverse dn
type Component' = [Attribute]
type DN' = [Component']
toDN' :: DN -> DN'
toDN' = map comp' . toList where
comp' (S a) = [a]
comp' (L as) = toList as
ordW8 :: Char -> Word8
ordW8 = fromIntegral . ord
quotation :: Word8
quotation = ordW8 '"'
specialChars :: [Word8]
specialChars = map ordW8 [',', '=', '+', '<', '>', '#', ';']
data LdifAttrValue
= LAttrValRaw ByteString
| LAttrValBase64 ByteString
deriving (Eq, Ord, Show)
ldifSafeBounds :: [Bound Char]
ldifSafeBounds =
[ ('\x01', '\x09')
, ('\x0B', '\x0C')
, ('\x0E', '\x7F')
]
ldifSafeInitBounds :: [Bound Char]
ldifSafeInitBounds =
[ ('\x01', '\x09')
, ('\x0B', '\x0C')
, ('\x0E', '\x1F')
, ('\x21', '\x39')
, exact '\x3B'
, ('\x3D', '\x7F')
]