filepath
filepath copied to clipboard
Provide conversions between PosixPath and WindowsPath
https://github.com/haskell/tar/pull/88 introduces
-- | We assume UTF-8 on posix and UTF-16 on windows.
toWindowsPath :: MonadThrow m => PosixPath -> m WindowsPath
toWindowsPath posix = do
str <- PFP.decodeUtf posix
win <- WFP.encodeUtf str
pure $ WS.map (\c -> if WFP.isPathSeparator c then WFP.pathSeparator else c) win
-- | We assume UTF-8 on posix and UTF-16 on windows.
toPosixPath :: MonadThrow m => WindowsPath -> m PosixPath
toPosixPath win = do
str <- WFP.decodeUtf win
posix <- PFP.encodeUtf str
pure $ PS.map (\c -> if PFP.isPathSeparator c then PFP.pathSeparator else c) posix
IMHO such utilities should better be provided by filepath itself, ideally optimized to a single pass without any intermediate structures.
Our primitives rely on the TextEncoding modules in base and use peekCStringLen etc.
See:
-- | Decode with the given 'TextEncoding'.
decodeWithTE :: TextEncoding -> BS8.ShortByteString -> Either EncodingException String
decodeWithTE enc ba = unsafePerformIO $ do
r <- try @SomeException $ BS8.useAsCStringLen ba $ \fp -> GHC.peekCStringLen enc fp
evaluate $ force $ first (flip EncodingError Nothing . displayException) r
-- | Encode with the given 'TextEncoding'.
encodeWithTE :: TextEncoding -> String -> Either EncodingException BS8.ShortByteString
encodeWithTE enc str = unsafePerformIO $ do
r <- try @SomeException $ GHC.withCStringLen enc str $ \cstr -> BS8.packCStringLen cstr
evaluate $ force $ first (flip EncodingError Nothing . displayException) r
The encoders/decoders API don't work well with non-String afair: https://hackage.haskell.org/package/base-4.19.0.0/docs/GHC-IO-Encoding.html
Because e.g. TextEncoder is fixed to char: type TextDecoder state = BufferCodec Word8 CharBufElem state.
How do you propose we get the API with TextEncoding for free and avoid intermediate representations? Can we not just rely on list fusion or so?
Can we not just rely on list fusion or so?
Given that PFP.decodeUtf is monadic, all effects must happen before we proceed to the next line. This almost certainly prevents any list fusion.
I suggest to write toWindowsPath and toPosixPath manually, without reliance on GHC.IO.Encoding. UTF-8 to UTF-16 and back conversion is reasonably simple.
That sounds hard. Can we cry for help?