@@ -28,6 +28,9 @@ module Data.Text.Encoding
2828 , decodeUtf32LE
2929 , decodeUtf32BE
3030
31+ -- ** Catchable failure
32+ , decodeUtf8'
33+
3134 -- ** Controllable error handling
3235 , decodeUtf8With
3336 , decodeUtf16LEWith
@@ -43,11 +46,12 @@ module Data.Text.Encoding
4346 , encodeUtf32BE
4447 ) where
4548
49+import Control.Exception (evaluate, try)
4650import Data.Bits ((.&.))
4751import Data.ByteString as B
4852import Data.ByteString.Internal as B
4953import Data.ByteString.Unsafe as B
50−import Data.Text.Encoding.Error (OnDecodeError, strictDecode)
54+import Data.Text.Encoding.Error (OnDecodeError, UnicodeException, strictDecode)
5155import Data.Text.Internal (Text(..), textP)
5256import Data.Text.UnsafeChar (ord, unsafeWrite)
5357import Data.Text.UnsafeShift (shiftL, shiftR)
@@ -116,18 +120,26 @@ decodeUtf8With onErr bs = textP (fst a) 0 (snd a)
116120 desc = "Data.Text.Encoding.decodeUtf8: Invalid UTF-8 stream"
117121{-# INLINE[0] decodeUtf8With #-}
118122
119−-- | Decode a 'ByteString' containing UTF-8 encoded text.
123+-- | Decode a 'ByteString' containing known-valid UTF-8 encoded text.
120124--
121125-- If the input contains any invalid UTF-8 data, an exception will be
122−-- thrown. For more control over the handling of invalid data, use
126+-- thrown that cannot be caught in pure code. For more control over
127+-- the handling of invalid data, use 'decodeUtf8'' or
123128-- 'decodeUtf8With'.
124129decodeUtf8 :: ByteString -> Text
125130decodeUtf8 = decodeUtf8With strictDecode
126131{-# INLINE[0] decodeUtf8 #-}
127−
128132{-# RULES "STREAM stream/decodeUtf8 fusion" [1]
129133 forall bs. F.stream (decodeUtf8 bs) = E.streamUtf8 strictDecode bs #-}
130134
135+-- | Decode a 'ByteString' containing UTF-8 encoded text..
136+--
137+-- If the input contains any invalid UTF-8 data, the relevant
138+-- exception will be returned, otherwise the decoded text.
139+decodeUtf8' :: ByteString -> Either UnicodeException Text
140+decodeUtf8' = unsafePerformIO . try . evaluate . decodeUtf8With strictDecode
141+{-# INLINE decodeUtf8' #-}
142+
131143-- | Encode text using UTF-8 encoding.
132144encodeUtf8 :: Text -> ByteString
133145encodeUtf8 (Text arr off len) = unsafePerformIO $ do