diff options
| author | Paul Oliver <contact@pauloliver.dev> | 2025-02-07 17:10:05 +0000 | 
|---|---|---|
| committer | Paul Oliver <contact@pauloliver.dev> | 2025-02-18 20:35:35 +0000 | 
| commit | ab4591cb0e074ce98c24645cdb80cb5012aed566 (patch) | |
| tree | 98451fa7e042e49ea83f265866754f3f6a3b406f /hsm-readline/Hsm/Readline.hs | |
Initial
Diffstat (limited to 'hsm-readline/Hsm/Readline.hs')
| -rw-r--r-- | hsm-readline/Hsm/Readline.hs | 50 | 
1 files changed, 50 insertions, 0 deletions
diff --git a/hsm-readline/Hsm/Readline.hs b/hsm-readline/Hsm/Readline.hs new file mode 100644 index 0000000..8a0c232 --- /dev/null +++ b/hsm-readline/Hsm/Readline.hs @@ -0,0 +1,50 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Hsm.Readline +  ( readline +  , allocateReadline +  ) where + +import Control.IO.Region (Region, alloc_) +import Data.Text (Text, pack) +import Data.Typeable (Proxy(Proxy), Typeable, typeRep) +import Hsm.Log qualified as L +import System.Console.Haskeline qualified as H +import System.Console.Haskeline.IO qualified as H +import Text.Read (readEither) + +logMsg :: Text -> IO () +logMsg = L.logMsg ["readline"] + +readline :: +     forall a. (Read a, Show a, Typeable a) +  => H.InputState +  -> IO (Maybe a) +readline handle = do +  logMsg $ "Expecting value of type " <> pack (show $ typeRep $ Proxy @a) +  valueMaybe <- queryInput +  maybe (return Nothing) parseValueStr valueMaybe +  where +    queryInput = +      H.queryInput handle +        $ H.handleInterrupt (return Nothing) +        $ H.withInterrupt +        $ H.getInputLine "% " +    parseValueStr valueStr = +      case readEither @a valueStr of +        Right commandValue -> do +          logMsg $ "Parsed value " <> pack (show commandValue) +          return $ Just commandValue +        Left err -> do +          logMsg $ pack err +          readline handle + +allocateReadline :: Region -> IO H.InputState +allocateReadline region = alloc_ region initializeInput cancelInput +  where +    initializeInput = do +      logMsg "Initializing input with default settings" +      H.initializeInput H.defaultSettings +    cancelInput handle = do +      logMsg "Cancelling input" +      H.cancelInput handle  | 
