{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} -- | Contains checks for custom properties of the map json module Properties (checkProperty) where import Control.Monad (unless) import Data.Text (Text) import Tiled2 (Layer (layerProperties), Property, propertyName, propertyValue) import Util (prettyprint) import LintWriter (LintWriter, complain, forbid, info, require, suggest, warn) -- | the point of this module -- -- given a property, check if it is valid. It gets a reference -- to its own layer since sometimes the presense of one property -- implies the presence or absense of another. -- -- The tests in here are meant to comply with the informal spec -- at https://workadventu.re/map-building -- -- I've attempted to build the LintWriter monad in a way -- that should make this readable even to non-Haskellers -- TODO: also pass the value of this property directly checkProperty :: Layer -> Property -> LintWriter () checkProperty layer prop = case propName of "jitsiRoom" -> do info $ "found jitsi room: " <> prettyprint (propertyValue prop) suggestPropertyValue "jitsiTrigger" "onaction" "jitsiTrigger" -> requireProperty "jitsiRoom" "jitsiUrl" -> isForbidden "jitsiConfig" -> isForbidden "jitsiClientConfig" -> isForbidden "jitsiRoomAdminTag" -> isForbidden "playAudio" -> do -- TODO: check for url validity? pure () "audioLoop" -> requireProperty "playAudio" "audioVolume" -> requireProperty "playAudio" "openWebsite" -> do suggestPropertyValue "openWebsiteTrigger" "onaction" require $ propertyValue prop "openWebsiteTrigger" -> requireProperty "openWebsite" "openWebsitePolicy" -> requireProperty "openWebsite" "exitUrl" -> pure () "startLayer" -> pure () -- could also make this a "hard error" (i.e. Left), but then it -- stops checking other properties as checkLayer short-circuits. _ -> warn $ "unknown property type " <> prettyprint propName where propName = propertyName prop -- | require some property in this layer requireProperty name = unless (hasProperty name layer) $ complain $ "property "<>prettyprint name<>" requires property "<>prettyprint propName -- | This property is forbidden and should not be used isForbidden = forbid $ "property " <> prettyprint propName <> " should not be used" -- TODO: check if the property has the correct value suggestPropertyValue :: Text -> Text -> LintWriter () suggestPropertyValue name value = unless (hasProperty name layer) $ suggest $ "set property " <> prettyprint name <> " to " <> prettyprint value -- | does this layer have the given property? hasProperty :: Text -> Layer -> Bool hasProperty name = any (\prop -> propertyName prop == name) . layerProperties