module Literate.Web.Semantics.Addresser where
import Data.Bool
+import Data.Eq (Eq)
import Data.Function (id, ($), (.))
+import Data.Functor ((<$>))
+import Data.List qualified as List
import Data.Maybe (Maybe (..))
import Data.Monoid (Monoid (..))
+import Data.Ord (Ord)
import Data.Semigroup (Semigroup (..))
+import Data.Text qualified as Text
import GHC.Generics (Generic)
import Literate.Web.Syntaxes
import Literate.Web.Types.URL
import Symantic qualified as Sym
+import System.FilePath qualified as Sys
import Text.Show (Show (..))
-- * Type 'Addresser'
address :: Addresser a -> a --> Address
address router = unAddresser router id
-instance PathSegmentable (Addresser) where
- pathSegment s = Addresser \f -> f Address{addressPath = [s]}
+instance PathSegmentable Addresser where
+ pathSegment s = Addresser \f -> f Address{addressSegs = [s], addressExts = []}
instance Sym.SumFunctor Addresser where
a <+> b = Addresser \n -> (unAddresser a n, unAddresser b n)
instance Sym.ProductFunctor Addresser where
- a <.> b = Addresser \k -> unAddresser a \aA -> unAddresser b \bA -> k (bA <> aA)
- a <. b = Addresser \k -> unAddresser a \aA -> unAddresser b \bA -> k (bA <> aA)
- a .> b = Addresser \k -> unAddresser a \aA -> unAddresser b \bA -> k (bA <> aA)
+ a <.> b = Addresser \k -> unAddresser a \aA -> unAddresser b \bA -> k (aA <> bA)
+ a <. b = Addresser \k -> unAddresser a \aA -> unAddresser b \bA -> k (aA <> bA)
+ a .> b = Addresser \k -> unAddresser a \aA -> unAddresser b \bA -> k (aA <> bA)
instance
( Generic a
, Sym.EoTOfRep a
where
-- dataType :: sem (Sym.EoT (Sym.ADT a)) -> sem a
dataType a = Addresser (\a2n -> Sym.funOftof (unAddresser a a2n) . Sym.eotOfadt)
-instance (Sym.IsToF a ~ 'False) => Optionable a Addresser where
+instance Sym.IsToF a ~ 'False => Optionable a Addresser where
optional aA = Addresser \k -> \case
Nothing -> k mempty
Just a -> unAddresser aA k a
-instance (end ~ Address) => Responsable a ts m (Addresser) where
+instance end ~ Address => Responsable a ts m (Addresser) where
response = Addresser ($ mempty)
-- ** Type 'Address'
-newtype Address = Address
- { addressPath :: [PathSegment]
+data Address = Address
+ { addressSegs :: [PathSegment]
+ , addressExts :: [PathSegment]
}
- deriving (Show)
-instance Semigroup (Address) where
- Address a <> Address b = Address (a <> b)
-instance Monoid (Address) where
- mempty = Address []
+ deriving (Eq, Ord, Show)
+instance Semigroup Address where
+ x <> y =
+ Address
+ { addressSegs = addressSegs x <> addressSegs y
+ , addressExts = addressExts x <> addressExts y
+ }
+instance Monoid Address where
+ mempty = Address{addressSegs = [], addressExts = []}
+
+addressFile :: Address -> Sys.FilePath
+addressFile addr =
+ List.intercalate "." $
+ encodePath (addressSegs addr)
+ : (Text.unpack . encodePathSegment <$> addressExts addr)