@@ -13,23 +13,25 @@ module Evdev.Stream (
13
13
import Data.Bool
14
14
import Data.Either.Extra
15
15
import Data.Functor
16
+ import Data.Maybe
16
17
import System.IO
17
18
import System.IO.Error
18
19
19
20
import Control.Concurrent (threadDelay )
20
21
import Data.Set (Set )
21
22
import qualified Data.Set as Set
22
- import qualified Data.ByteString.Char8 as BS
23
- import RawFilePath.Directory (RawFilePath ,doesFileExist ,listDirectory )
24
23
import qualified Streamly.FSNotify as N
25
24
import Streamly.FSNotify (FSEntryType (NotDir ),watchDirectory )
26
- import System.FilePath.ByteString ((</>) )
25
+ import qualified System.Directory.OsPath
26
+ import System.OsPath.Posix (PosixPath , (</>) , decodeUtf , encodeUtf )
27
27
28
28
import Streamly.Prelude (AsyncT , IsStream , MonadAsync , SerialT )
29
29
import qualified Streamly.Prelude as S
30
30
31
31
import Evdev
32
32
33
+ import System.OsString.Internal.Types (OsString (.. ))
34
+
33
35
-- TODO provide a 'group' operation on streams, representing packets as sets
34
36
35
37
-- | Read all events from a device.
@@ -48,7 +50,7 @@ readEventsMany ds = S.fromAsync $ do
48
50
readEvents' :: Device -> SerialT IO Event
49
51
50
52
-- | 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
52
54
makeDevices = S. mapM newDevice
53
55
54
56
-- | All events on all valid devices (in /\/dev\/input/).
@@ -77,15 +79,15 @@ allDevices =
77
79
newDevices :: (IsStream t , Monad (t IO )) => t IO Device
78
80
newDevices =
79
81
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 )
81
83
watch watching = \ case
82
- N. Added (BS. pack -> p) _ NotDir ->
84
+ N. Added (enc -> p) _ NotDir ->
83
85
tryNewDevice p <&> \ case
84
86
Right d -> -- success - return new device
85
87
(Just d, watching)
86
88
Left e -> -- fail - if it's only a permission error then watch for changes on device
87
89
(Nothing , applyWhen (isPermissionError e) (Set. insert p) watching)
88
- N. Modified (BS. pack -> p) _ NotDir ->
90
+ N. Modified (enc -> p) _ NotDir ->
89
91
if p `elem` watching then
90
92
tryNewDevice p <&> \ case
91
93
Right d -> -- success - no longer watch for changes
@@ -94,12 +96,14 @@ newDevices =
94
96
(Nothing , watching)
95
97
else -- this isn't an event we care about
96
98
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
98
100
return (Nothing , Set. delete p watching)
99
101
_ -> return (Nothing , watching)
100
102
tryNewDevice = printIOError . newDevice
103
+ enc = fromMaybe (error " bad fsnotify path conversion" ) . encodeUtf
104
+ dec = fromMaybe (error " bad fsnotify path conversion" ) . decodeUtf
101
105
in do
102
- (_,es) <- S. fromEffect $ watchDirectory (BS. unpack evdevDir) N. everything
106
+ (_,es) <- S. fromEffect $ watchDirectory (dec evdevDir) N. everything
103
107
scanMaybe watch Set. empty es
104
108
105
109
-- TODO just fix 'newDevices'
@@ -108,13 +112,15 @@ newDevices =
108
112
newDevices' :: (IsStream t , Monad (t IO )) => Int -> t IO Device
109
113
newDevices' delay =
110
114
let f = \ case
111
- N. Added (BS. pack -> p) _ NotDir -> do
115
+ N. Added (enc -> p) _ NotDir -> do
112
116
threadDelay delay
113
117
eitherToMaybe <$> tryNewDevice p
114
118
_ -> return Nothing
115
119
tryNewDevice = printIOError . newDevice
120
+ enc = fromMaybe (error " bad fsnotify path conversion" ) . encodeUtf
121
+ dec = fromMaybe (error " bad fsnotify path conversion" ) . decodeUtf
116
122
in do
117
- (_,es) <- S. fromEffect $ watchDirectory (BS. unpack evdevDir) N. everything
123
+ (_,es) <- S. fromEffect $ watchDirectory (dec evdevDir) N. everything
118
124
S. mapMaybeM f es
119
125
120
126
@@ -147,3 +153,9 @@ printIOError' = fmap eitherToMaybe . printIOError
147
153
-- apply the function iff the guard passes
148
154
applyWhen :: Bool -> (a -> a ) -> a -> a
149
155
applyWhen = 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