@@ -13,23 +13,25 @@ module Evdev.Stream (
1313import Data.Bool
1414import Data.Either.Extra
1515import Data.Functor
16+ import Data.Maybe
1617import System.IO
1718import System.IO.Error
1819
1920import Control.Concurrent (threadDelay )
2021import Data.Set (Set )
2122import qualified Data.Set as Set
22- import qualified Data.ByteString.Char8 as BS
23- import RawFilePath.Directory (RawFilePath ,doesFileExist ,listDirectory )
2423import qualified Streamly.FSNotify as N
2524import Streamly.FSNotify (FSEntryType (NotDir ),watchDirectory )
26- import System.FilePath.ByteString ((</>) )
25+ import qualified System.Directory.OsPath
26+ import System.OsPath.Posix (PosixPath , (</>) , decodeUtf , encodeUtf )
2727
2828import Streamly.Prelude (AsyncT , IsStream , MonadAsync , SerialT )
2929import qualified Streamly.Prelude as S
3030
3131import Evdev
3232
33+ import System.OsString.Internal.Types (OsString (.. ))
34+
3335-- TODO provide a 'group' operation on streams, representing packets as sets
3436
3537-- | Read all events from a device.
@@ -48,7 +50,7 @@ readEventsMany ds = S.fromAsync $ do
4850 readEvents' :: Device -> SerialT IO Event
4951
5052-- | Create devices for all paths in the stream.
51- makeDevices :: IsStream t => t IO RawFilePath -> t IO Device
53+ makeDevices :: IsStream t => t IO PosixPath -> t IO Device
5254makeDevices = S. mapM newDevice
5355
5456-- | All events on all valid devices (in /\/dev\/input/).
@@ -77,15 +79,15 @@ allDevices =
7779newDevices :: (IsStream t , Monad (t IO )) => t IO Device
7880newDevices =
7981 let -- 'watching' keeps track of the set of paths which have been added, but don't yet have the right permissions
80- watch :: Set RawFilePath -> N. Event -> IO (Maybe Device , Set RawFilePath )
82+ watch :: Set PosixPath -> N. Event -> IO (Maybe Device , Set PosixPath )
8183 watch watching = \ case
82- N. Added (BS. pack -> p) _ NotDir ->
84+ N. Added (enc -> p) _ NotDir ->
8385 tryNewDevice p <&> \ case
8486 Right d -> -- success - return new device
8587 (Just d, watching)
8688 Left e -> -- fail - if it's only a permission error then watch for changes on device
8789 (Nothing , applyWhen (isPermissionError e) (Set. insert p) watching)
88- N. Modified (BS. pack -> p) _ NotDir ->
90+ N. Modified (enc -> p) _ NotDir ->
8991 if p `elem` watching then
9092 tryNewDevice p <&> \ case
9193 Right d -> -- success - no longer watch for changes
@@ -94,12 +96,14 @@ newDevices =
9496 (Nothing , watching)
9597 else -- this isn't an event we care about
9698 return (Nothing , watching)
97- N. Removed (BS. pack -> p) _ NotDir -> -- device is gone - no longer watch for changes
99+ N. Removed (enc -> p) _ NotDir -> -- device is gone - no longer watch for changes
98100 return (Nothing , Set. delete p watching)
99101 _ -> return (Nothing , watching)
100102 tryNewDevice = printIOError . newDevice
103+ enc = fromMaybe (error " bad fsnotify path conversion" ) . encodeUtf
104+ dec = fromMaybe (error " bad fsnotify path conversion" ) . decodeUtf
101105 in do
102- (_,es) <- S. fromEffect $ watchDirectory (BS. unpack evdevDir) N. everything
106+ (_,es) <- S. fromEffect $ watchDirectory (dec evdevDir) N. everything
103107 scanMaybe watch Set. empty es
104108
105109-- TODO just fix 'newDevices'
@@ -108,13 +112,15 @@ newDevices =
108112newDevices' :: (IsStream t , Monad (t IO )) => Int -> t IO Device
109113newDevices' delay =
110114 let f = \ case
111- N. Added (BS. pack -> p) _ NotDir -> do
115+ N. Added (enc -> p) _ NotDir -> do
112116 threadDelay delay
113117 eitherToMaybe <$> tryNewDevice p
114118 _ -> return Nothing
115119 tryNewDevice = printIOError . newDevice
120+ enc = fromMaybe (error " bad fsnotify path conversion" ) . encodeUtf
121+ dec = fromMaybe (error " bad fsnotify path conversion" ) . decodeUtf
116122 in do
117- (_,es) <- S. fromEffect $ watchDirectory (BS. unpack evdevDir) N. everything
123+ (_,es) <- S. fromEffect $ watchDirectory (dec evdevDir) N. everything
118124 S. mapMaybeM f es
119125
120126
@@ -147,3 +153,9 @@ printIOError' = fmap eitherToMaybe . printIOError
147153-- apply the function iff the guard passes
148154applyWhen :: Bool -> (a -> a ) -> a -> a
149155applyWhen = flip $ bool id
156+
157+ -- TODO hmm unsure what to do here - at the very least move these...
158+ doesFileExist :: PosixPath -> IO Bool
159+ doesFileExist = System.Directory.OsPath. doesFileExist . OsString
160+ listDirectory :: PosixPath -> IO [PosixPath ]
161+ listDirectory = fmap (map getOsString) . System.Directory.OsPath. listDirectory . OsString
0 commit comments