System.IO.Utf8.Internal

with-utf8-1.1.0.0: Get your IO right on the first try

Safe Haskell | Safe-Inferred
Language | Haskell2010

System.IO.Utf8.Internal

Description

Internal functions that implement encoding selection logic.

Synopsis

- data EncodingAction
  - = Keep
  - | ChangeFromTo TextEncoding String
- chooseBestEncPure :: Bool -> Maybe String -> Maybe String
- chooseBestEnc :: Handle -> (Handle -> IO Bool) -> Maybe TextEncoding -> IO EncodingAction

# Documentation

data EncodingAction #

What to do with the encoding of the handle.

We return new encoding as string to simplify testing, because, it turns out, when you make an encoding with some name, the resulting encoding can have a different name.

The second constructor also contains the old encoding as a proof that the encoding is set to a new one only if there was a previous one in the first place. You probably think I am crazy, but I am not, it is just the simplest way to make the `hSetBestUtf8Enc` easy to write.

Constructors

Keep | Do nothing.
ChangeFromTo TextEncoding String | Change the first encoding to the second.

chooseBestEncPure #

Arguments

:: Bool | Is a terminal device?
-> Maybe String | Previous encoding name.
-> Maybe String |

Pure version of `chooseBestEnc`.

This function is not actually used in the library. It exists only for documentation purposes to demonstrate the logic. It is also used in tests to verify that the logic implemented is indeed this.

chooseBestEnc #

Arguments

:: Handle | Handle to choose encoding for.
-> (Handle -> IO Bool) | hIsTerminalDevice.
-> Maybe TextEncoding | Current encoding.
-> IO EncodingAction |

Choose the best encoding for a file handle.

This function implements the same logic as `chooseBestEncPure`, but in a way that is more optimal in terms of IO queries. In particular:

1. It receives both a handle and its current encoding, because the calling function will, most likely, need to know the current encoding (e.g. to be able to restore it), so we avoid repeating the query.
2. It first checks for the cases where it doesn't care whether the device is a terminal or not, so the query will be made only if really necessary.