module System.GPIO.Types where import BasicPrelude import Data.String.Conversions -- Core Types ------------------------------------------------------------------ data Pin = P18 | P23 | P24 | P25 deriving (Eq, Show, Enum) pinNumDict :: [(Pin, Int)] pinNumDict = [ (P18, 18) , (P23, 23) , (P24, 24) , (P25, 25) ] pinNum :: Pin -> Int pinNum p = fromMaybe unexpectedError (lookup p pinNumDict) where unexpectedError = error $ convertString ("Unexpected error. " ++ show p ++ " not defined in 'pinNumDict'") pinNumT :: Pin -> Text pinNumT = show . pinNum fromInt :: Int -> Maybe Pin fromInt i = lookup i (swap <$> pinNumDict) data ActivePin (a :: Dir) where ReaderPin :: Pin -> ActivePin 'In WriterPin :: Pin -> ActivePin 'Out deriving instance Show (ActivePin a) pin :: ActivePin a -> Pin pin = \case ReaderPin p -> p WriterPin p -> p data Dir = In | Out deriving (Show) instance ToText Dir where toText = \case In -> "in" Out -> "out" instance FromText Dir where fromText = \case "in" -> Right In "out" -> Right Out x -> Left ("Cannot parse \"Dir\" from \"" <> x <> "\"") data Value = HI | LO deriving (Show) instance ToText Value where toText = \case HI -> "1" LO -> "0" instance FromText Value where fromText = \case "1" -> Right HI "0" -> Right LO x -> Left ("Cannot parse \"Value\" from \"" <> x <> "\"") -- We are going to do a lot of reading/writing to files w/ custom data types. -- Create a small interface to keep conversions consistent. class ToText a where toText :: a -> Text class FromText a where fromText :: Text -> Either Text a