packages feed

sport 0.2.0.0 → 1.0.0.0

raw patch · 6 files changed

+86/−26 lines, 6 filesdep +sportdep ~basenew-component:exe:sportPVP ok

version bump matches the API change (PVP)

Dependencies added: sport

Dependency ranges changed: base

API changes (from Hackage documentation)

- Sport.Sport: instance GHC.Internal.Read.Read Sport.Sport.SportException
+ Sport: isOpenSport :: Sport -> STM Bool
+ Sport.Sport: instance GHC.Internal.Show.Show Sport.Sport.SportCfg
+ Sport.Sport: isOpenSport :: Sport -> STM Bool
- Sport: SportAlreadyOpen :: SportException
+ Sport: SportAlreadyOpen :: String -> SportException
- Sport.Sport: SportAlreadyOpen :: SportException
+ Sport.Sport: SportAlreadyOpen :: String -> SportException

Files

CHANGELOG.md view
@@ -1,5 +1,11 @@ # Revision history for sport +## 1.0.0.0 -- 4-30-2026++* Fix `SportAlreadyOpen` bug+* Update exception types+* Add `isOpenSport` to STM API+ ## 0.2.0.0 -- 4-21-2026  * Expose current configuration in STM
+ exe/Main.hs view
@@ -0,0 +1,6 @@+module Main where++import Sport.Main++main :: IO ()+main = sportMain
lib/Sport.hs view
@@ -17,6 +17,7 @@   , runSport   , -- *** Open & Close     openSport+  , isOpenSport   , getSportCfg   , defSportCfg   , SportCfg(..)
lib/Sport/Sport.hs view
@@ -5,6 +5,7 @@   , withSport   , runSport   , openSport+  , isOpenSport   , getSportCfg   , defSportCfg   , SportCfg(..)@@ -52,6 +53,14 @@   | Open SportCfg Handle   deriving Eq +isOpen :: State -> Bool+isOpen Open{} = True+isOpen _      = False++-- | Check if serial port is open+isOpenSport :: Sport -> STM Bool+isOpenSport = fmap isOpen . readTVar . state+ data RdCmd   = Rd Int (TMVar (Either SomeException ByteString))   | RdSome Int (TMVar (Either SomeException ByteString))@@ -71,7 +80,7 @@   , rtimeout   :: Maybe Int   , excl       :: Bool -- ^ exclusive   }-  deriving Eq+  deriving (Eq, Show)  -- | Binary with no buffering defSportCfg :: SportCfg@@ -90,13 +99,14 @@ -- | Open the serial port. Throw 'SportAlreadyOpen' if the -- serial port was already opened. openSport :: Sport -> SportCfg -> IO ()-openSport (Sport s _ _) cfg = do+openSport (Sport s _ _) cfg' = do   res <- newEmptyTMVarIO   atomically $ do     st <- readTVar s     case st of-      Closed -> writeTVar s $ Opening cfg res-      _      -> throwSTM SportAlreadyOpen+      Closed        -> writeTVar s $ Opening cfg' res+      Opening cfg _ -> throwSTM $ SportAlreadyOpen $ path cfg+      Open    cfg _ -> throwSTM $ SportAlreadyOpen $ path cfg   atomically $ do     result <- takeTMVar res     case result of@@ -198,9 +208,12 @@  runState :: Sport -> State -> IO () runState s st = case st of-  Closed          -> waitNewState s st-  Opening cfg res -> handleException res $ opening s cfg res-  Open _ serial   -> runConcurrently $ asum $ map Concurrently+  Closed -> waitNewState s st+  Opening cfg res ->+    handleException res $+      opening s cfg res+        `onException` atomically (writeTVar (state s) Closed)+  Open _ serial -> runConcurrently $ asum $ map Concurrently     [ waitNewState s st     , readHandler s serial     , writeHandler s serial@@ -259,7 +272,12 @@     -- | User required an open sport but it was closed.   = SportClosed     -- | User attempted to open a serial port that was already open.-  | SportAlreadyOpen-  deriving (Eq, Read, Show)+  | SportAlreadyOpen String+  deriving Eq++instance Show SportException where+  show e = "sport exception: " <> case e of+    SportClosed -> "serial port closed"+    SportAlreadyOpen p -> "serial port already open: " <> p  instance Exception SportException
sport.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.0 name:               sport-version:            0.2.0.0+version:            1.0.0.0 synopsis:           UNIX serial port description:        Concurrent serial IO license:            MIT@@ -18,7 +18,7 @@   location: https://github.com/standardsemiconductor/sport  library-  ghc-options:      -Wall -O2+  ghc-options:      -Wall -Wunused-packages -O2   default-language: Haskell2010   hs-source-dirs:   lib   exposed-modules:  Sport,@@ -31,19 +31,22 @@                     stm,                     unix ---executable sport---  ghc-options:      -Wall -O2 -threaded---  default-language: Haskell2010---  hs-source-dirs:   exe---  main-is:          Main.hs---  build-depends:    base,---                    sport+executable sport+  ghc-options:      -Wall -O2 -threaded+  default-language: Haskell2010+  hs-source-dirs:   exe+  main-is:          Main.hs+  build-depends:    base,+                    sport ---test-suite test---  ghc-options:      -Wall---  default-language: Haskell2010---  hs-source-dirs:   test---  type:             exitcode-stdio-1.0---  main-is:          Main.hs---  build-depends:    base,---                    sport+test-suite test+  ghc-options:      -Wall -Wunused-packages -O2 -threaded+  default-language: Haskell2010+  hs-source-dirs:   test+  type:             exitcode-stdio-1.0+  main-is:          Main.hs+  build-depends:    async,+                    base,+                    bytestring,+                    sport,+                    stm
+ test/Main.hs view
@@ -0,0 +1,26 @@+module Main (main) where++import Control.Concurrent.Async+import Control.Concurrent.STM+import qualified Data.ByteString.Lazy as BS+import Sport+import System.IO++main :: IO ()+main = do+  hSetBuffering stdout NoBuffering+  putStrLn "SPORT TEST"+  s <- newSportIO+  race_ (runSport s) $ do+    putStr "OPENING..."+    openSport s defSportCfg{speed=B19200}+    putStrLn "DONE"+    let bs = BS.replicate 256 0xDC+    putStr "XFERING..."+    bs' <- fst <$> concurrently (readSport s 10) (writeSport s bs)+    putStrLn "DONE"+    putStr "COMPARING..."+    putStrLn $ if BS.take 10 bs == bs' then "PASS" else "FAIL"+    putStr "CLOSING..."+    closeSport s+    putStrLn "DONE"