mirror of
https://github.com/serokell/haskell-with-utf8.git
synced 2024-08-15 09:40:21 +03:00
Implement hWithEncoding
This function allows one to not only safely set the best encoding on a file descriptor, but also restore the previous one. The idea is that it will be used on file descriptors that come from the outside and so we don’t know how they were used and will be used after us.
This commit is contained in:
parent
35e2ea5ce2
commit
5b98b490bc
@ -14,6 +14,7 @@ Initial release.
|
||||
|
||||
- `withUtf8StdHandles`
|
||||
- `hSetEncoding`
|
||||
- `hWithEncoding`
|
||||
- `openFile`
|
||||
- `withFile`
|
||||
- `readFile`
|
||||
|
11
README.md
11
README.md
@ -57,17 +57,16 @@ All these functions will make sure that the content will be treated as if it
|
||||
was encoded in UTF-8 (it is 2020, what else can it be encoded in?).
|
||||
|
||||
If, for some reason, you really need to use `withFile`/`openFile` from `base`,
|
||||
just call `hSetEncoding h`, where `h` is your handle and `hSetEncoding` comes
|
||||
from `System.IO.Utf8` for your convenience:
|
||||
or you got your file handle from somewhere else, wrap the code that works
|
||||
with it in a call to `hWithEncoding` from `System.IO.Utf8`:
|
||||
|
||||
```haskell
|
||||
import qualified System.IO as IO
|
||||
import qualified System.IO.Utf8 as Utf8
|
||||
|
||||
doSomethingWithAFile :: IO ()
|
||||
doSomethingWithAFile = IO.withFile "file.txt" IO.ReadMode $ \h -> do
|
||||
Utf8.hSetEncoding h
|
||||
{- ... work with the file ... -}
|
||||
doSomethingWithAFile :: IO.Handle -> IO ()
|
||||
doSomethingWithAFile h = Utf8.hWithEncoding h $ do
|
||||
{- ... work with the file ... -}
|
||||
```
|
||||
|
||||
### Step 4: Write files using UTF-8
|
||||
|
@ -24,6 +24,7 @@ module System.IO.Utf8
|
||||
( withUtf8StdHandles
|
||||
|
||||
, hSetEncoding
|
||||
, hWithEncoding
|
||||
|
||||
, openFile
|
||||
, withFile
|
||||
@ -66,13 +67,10 @@ hSetBestUtf8Enc h = liftIO $ IO.hGetEncoding h >>= \case
|
||||
-- After the action finishes, restores the original encodings.
|
||||
withUtf8StdHandles :: IO a -> IO a
|
||||
withUtf8StdHandles action =
|
||||
withConfiguredHandle stdin $
|
||||
withConfiguredHandle stdout $
|
||||
withConfiguredHandle stderr $
|
||||
hWithEncoding stdin $
|
||||
hWithEncoding stdout $
|
||||
hWithEncoding stderr $
|
||||
action
|
||||
where
|
||||
withConfiguredHandle :: IO.Handle -> IO a -> IO a
|
||||
withConfiguredHandle h = bracket (hSetBestUtf8Enc h) ($ h) . const
|
||||
|
||||
|
||||
-- | Set handle encoding to the best possible.
|
||||
@ -93,6 +91,13 @@ withUtf8StdHandles action =
|
||||
hSetEncoding :: MonadIO m => IO.Handle -> m ()
|
||||
hSetEncoding = liftIO . void . hSetBestUtf8Enc
|
||||
|
||||
-- | Temporarily set handle encoding to the best possible.
|
||||
--
|
||||
-- This is like 'hSetEncoding', but it will restore the encoding
|
||||
-- to the previous one when the action is done.
|
||||
hWithEncoding :: (MonadIO m, MonadMask m) => IO.Handle -> m r -> m r
|
||||
hWithEncoding h = bracket (hSetBestUtf8Enc h) ($ h) . const
|
||||
|
||||
|
||||
-- | Like @openFile@, but sets the file encoding to UTF-8, regardless
|
||||
-- of the current locale.
|
||||
|
Loading…
Reference in New Issue
Block a user