2-- Module : Streamly.Internal.Console.Stdio
3-- Copyright : (c) 2018 Composewell Technologies
5-- License : BSD-3-Clause
6-- Maintainer : streamly@composewell.com
7-- Stability : experimental
10module Streamly.Internal.Console.Stdio
19 -- , getStringsWith -- get strings using the supplied decoding
20 -- , getStrings -- get strings of complete chars,
21 -- leave any partial chars for next string
22 -- , getStringsLn -- get lines decoded as char strings
27 , putBytes -- Buffered (32K)
31 , putChunks -- Unbuffered
40import Control.Monad.IO.Class (MonadIO(..))
41import Data.Word (Word8)
42import System.IO (stdin, stdout, stderr)
43import Prelude hiding (read)
45import Streamly.Internal.Data.Array.Foreign.Type (Array(..))
46import Streamly.Internal.Data.Stream.Serial (SerialT)
47import Streamly.Internal.Data.Unfold (Unfold)
48import Streamly.Internal.Data.Fold (Fold)
50import qualified Streamly.Internal.Data.Array.Foreign as Array
51import qualified Streamly.Internal.Data.Stream.IsStream as Stream
52import qualified Streamly.Internal.Data.Unfold as Unfold
53import qualified Streamly.Internal.FileSystem.Handle as Handle
54import qualified Streamly.Internal.Unicode.Stream as Unicode
56-------------------------------------------------------------------------------
58-------------------------------------------------------------------------------
60-- | Unfold standard input into a stream of 'Word8'.
64read :: MonadIO m => Unfold m () Word8
65read = Unfold.lmap (\() -> stdin) Handle.read
67-- | Read a byte stream from standard input.
69-- > getBytes = Handle.getBytes stdin
70-- > getBytes = Stream.unfold Stdio.read ()
74{-# INLINE getBytes #-}
75getBytes :: MonadIO m => SerialT m Word8
76getBytes = Handle.getBytes stdin
78-- | Read a character stream from Utf8 encoded standard input.
80-- > getChars = Unicode.decodeUtf8 Stdio.getBytes
84{-# INLINE getChars #-}
85getChars :: MonadIO m => SerialT m Char
86getChars = Unicode.decodeUtf8 getBytes
88-- | Unfolds standard input into a stream of 'Word8' arrays.
91{-# INLINE readChunks #-}
92readChunks :: MonadIO m => Unfold m () (Array Word8)
93readChunks = Unfold.lmap (\() -> stdin) Handle.readChunks
95-- | Read a stream of chunks from standard input. The maximum size of a single
96-- chunk is limited to @defaultChunkSize@. The actual size read may be less
97-- than @defaultChunkSize@.
99-- > getChunks = Handle.getChunks stdin
100-- > getChunks = Stream.unfold Stdio.readChunks ()
104{-# INLINE getChunks #-}
105getChunks :: MonadIO m => SerialT m (Array Word8)
106getChunks = Handle.getChunks stdin
109-- | Read UTF8 encoded lines from standard input.
111-- You may want to process the input byte stream directly using appropriate
112-- folds for more efficient processing.
116{-# INLINE getChunksLn #-}
117getChunksLn :: MonadIO m => SerialT m (Array Word8)
118getChunksLn = (Stream.splitWithSuffix (== '\n') f) getChars
120 -- XXX Need to implement Fold.unfoldMany, should be easy for
121 -- non-terminating folds, but may be tricky for terminating folds. See
122 -- Array Stream folds.
123 where f = Fold.unfoldMany Unicode.readCharUtf8 Array.write
126-------------------------------------------------------------------------------
128-------------------------------------------------------------------------------
130-- | Fold a stream of 'Word8' to standard output.
134write :: MonadIO m => Fold m Word8 ()
135write = Handle.write stdout
137-- | Fold a stream of 'Word8' to standard error.
140{-# INLINE writeErr #-}
141writeErr :: MonadIO m => Fold m Word8 ()
142writeErr = Handle.write stderr
144-- | Write a stream of bytes to standard output.
146-- > putBytes = Handle.putBytes stdout
147-- > putBytes = Stream.fold Stdio.write
151{-# INLINE putBytes #-}
152putBytes :: MonadIO m => SerialT m Word8 -> m ()
153putBytes = Handle.putBytes stdout
155-- | Encode a character stream to Utf8 and write it to standard output.
157-- > putChars = Stdio.putBytes . Unicode.encodeUtf8
161{-# INLINE putChars #-}
162putChars :: MonadIO m => SerialT m Char -> m ()
163putChars = putBytes . Unicode.encodeUtf8
165-- | Fold a stream of @Array Word8@ to standard output.
168{-# INLINE writeChunks #-}
169writeChunks :: MonadIO m => Fold m (Array Word8) ()
170writeChunks = Handle.writeChunks stdout
172-- | Fold a stream of @Array Word8@ to standard error.
175{-# INLINE writeErrChunks #-}
176writeErrChunks :: MonadIO m => Fold m (Array Word8) ()
177writeErrChunks = Handle.writeChunks stderr
179-- | Write a stream of chunks to standard output.
181-- > putChunks = Handle.putChunks stdout
182-- > putChunks = Stream.fold Stdio.writeChunks
186{-# INLINE putChunks #-}
187putChunks :: MonadIO m => SerialT m (Array Word8) -> m ()
188putChunks = Handle.putChunks stdout
190-------------------------------------------------------------------------------
192-------------------------------------------------------------------------------
194-- XXX We need to write transformations as pipes so that they can be applied to
195-- folds as well as unfolds/streams. Non-backtracking (one-to-one, one-to-many,
196-- filters, reducers) transformations may be easy so we can possibly start with
199-- | Write a stream of strings to standard output using the supplied encoding.
200-- Output is flushed to the device for each string.
204{-# INLINE putStringsWith #-}
205putStringsWith :: MonadIO m
206 => (SerialT m Char -> SerialT m Word8) -> SerialT m String -> m ()
207putStringsWith encode = putChunks . Unicode.encodeStrings encode
209-- | Write a stream of strings to standard output using UTF8 encoding. Output
210-- is flushed to the device for each string.
214{-# INLINE putStrings #-}
215putStrings :: MonadIO m => SerialT m String -> m ()
216putStrings = putStringsWith Unicode.encodeUtf8
218-- | Like 'putStrings' but adds a newline at the end of each string.
220-- XXX This is not portable, on Windows we need to use "\r\n" instead.
224{-# INLINE putStringsLn #-}
225putStringsLn :: MonadIO m => SerialT m String -> m ()
228 . Stream.intersperseSuffix (return $ Array.fromList [10])
229 . Unicode.encodeStrings Unicode.encodeUtf8
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list