module Network.Email.Header.Layout
( Layout
, layout
, span
, break
, position
, nicest
) where
import Prelude hiding (span, break)
type LayoutStep a = Int -> (Int -> Bool, a)
newtype Layout a = Layout { runLayout :: LayoutStep a -> LayoutStep a }
instance Semigroup (Layout a) where
(<>) a b = Layout $ runLayout a . runLayout b
instance Monoid (Layout a) where
mempty = Layout id
mappend = (<>)
layout :: Monoid a => Int -> Layout a -> a
layout p l = snd $ runLayout l (const (const True, mempty)) p
span :: Monoid a => Int -> a -> Layout a
span k s = Layout $ \c p ->
let ~(fits, b) = c (p + k)
in (\w -> p <= w && fits w, s <> b)
break :: Int -> Layout a
break i = Layout $ \c p ->
let ~(_, b) = c i
in (\w -> p <= w, b)
position :: (Int -> Layout a) -> Layout a
position f = Layout $ \c p -> runLayout (f p) c p
nicest :: Int -> Layout a -> Layout a -> Layout a
nicest w x y = Layout $ \c p ->
let a@(fits, _) = runLayout x c p
b = runLayout y c p
in if fits w then a else b