iri 0.5.1 → 0.5.1.1
raw patch · 18 files changed
+224/−246 lines, 18 filesdep ~basedep ~text-builder
Dependency ranges changed: base, text-builder
Files
- iri.cabal +75/−95
- library/Iri/CodePointPredicates/Core.hs +1/−1
- library/Iri/CodePointPredicates/Rfc3987.hs +1/−1
- library/Iri/Data/Functions.hs +1/−1
- library/Iri/Data/Instances/Lift.hs +2/−2
- library/Iri/Data/Instances/Show.hs +2/−2
- library/Iri/MonadPlus.hs +2/−2
- library/Iri/Optics/Defs.hs +5/−5
- library/Iri/Parsing/Attoparsec/ByteString.hs +29/−29
- library/Iri/Parsing/Attoparsec/Text.hs +18/−18
- library/Iri/Parsing/ByteString.hs +5/−5
- library/Iri/Parsing/Text.hs +2/−2
- library/Iri/QuasiQuoter.hs +4/−4
- library/Iri/Rendering/ByteString.hs +2/−2
- library/Iri/Rendering/Ptr/Poking.hs +11/−11
- library/Iri/Rendering/Text/Internal.hs +18/−18
- library/Iri/Rendering/TextBuilder/Internal.hs +42/−44
- test/Main.hs +4/−4
iri.cabal view
@@ -1,34 +1,31 @@ cabal-version: 3.0-name: iri-version: 0.5.1-category: URI, URL, IRI, Network-synopsis: RFC-based resource identifier library+name: iri+version: 0.5.1.1+category: URI, URL, IRI, Network+synopsis: RFC-compliant universal resource identifier library (URL, URI, IRI) description: This library provides a universal data model for representation of URI, URL and IRI. It comes packed with parsing, rendering and serialisation functionality. It is implemented in conformance with the RFC-3986 and RFC-3987 specifications and is intended as a standard tool for all tasks related to resource identifiers. -homepage: https://github.com/nikita-volkov/iri-bug-reports: https://github.com/nikita-volkov/iri/issues-author: Nikita Volkov <nikita.y.volkov@mail.ru>-maintainer: Nikita Volkov <nikita.y.volkov@mail.ru>-copyright: (c) 2017 Nikita Volkov-license: MIT-license-file: LICENSE+homepage: https://github.com/nikita-volkov/iri+bug-reports: https://github.com/nikita-volkov/iri/issues+author: Nikita Volkov <nikita.y.volkov@mail.ru>+maintainer: Nikita Volkov <nikita.y.volkov@mail.ru>+copyright: (c) 2017 Nikita Volkov+license: MIT+license-file: LICENSE source-repository head- type: git- location: git://github.com/nikita-volkov/iri.git+ type: git+ location: https://github.com/nikita-volkov/iri -library- hs-source-dirs: library- default-language: Haskell2010+common base+ default-language: Haskell2010 default-extensions:- NoImplicitPrelude- NoMonomorphismRestriction- Arrows BangPatterns+ BlockArguments ConstraintKinds DataKinds DefaultSignatures@@ -37,33 +34,56 @@ DeriveFunctor DeriveGeneric DeriveTraversable+ DerivingStrategies EmptyDataDecls FlexibleContexts FlexibleInstances FunctionalDependencies GADTs GeneralizedNewtypeDeriving- ImportQualifiedPost LambdaCase LiberalTypeSynonyms MagicHash MultiParamTypeClasses MultiWayIf+ NoImplicitPrelude+ NoMonomorphismRestriction+ NumericUnderscores OverloadedStrings ParallelListComp PatternGuards- PatternSynonyms QuasiQuotes RankNTypes RecordWildCards ScopedTypeVariables StandaloneDeriving+ StrictData TemplateHaskell TupleSections+ TypeApplications TypeFamilies TypeOperators UnboxedTuples+ ViewPatterns +common executable+ import: base+ ghc-options:+ -O2+ -threaded+ -with-rtsopts=-N+ -rtsopts+ -funbox-strict-fields++common test+ import: base+ ghc-options:+ -threaded+ -with-rtsopts=-N++library+ import: base+ hs-source-dirs: library exposed-modules: Iri.Data Iri.Optics@@ -101,89 +121,49 @@ Iri.Vector build-depends:- , attoparsec >=0.13 && <0.15- , base >=4.15 && <5- , bytestring >=0.10 && <0.13- , contravariant >=1.4 && <2- , hashable >=1.2 && <2- , ip >=1.7.8 && <2- , iri:punycode- , profunctors >=5.2 && <6- , ptr >=0.16.1 && <0.17- , template-haskell >=2.17 && <3- , text >=2 && <3- , text-builder >=0.6.7.2 && <0.7- , th-lift >=0.8 && <0.9- , th-lift-instances >=0.1.20 && <0.2- , unordered-containers >=0.2 && <0.3- , vector >=0.13 && <0.14- , vector-builder >=0.3.4 && <0.4- , vector-instances >=3.4 && <4- , wide-word >=0.1.6 && <2+ attoparsec >=0.13 && <0.15,+ base >=4.15 && <5,+ bytestring >=0.10 && <0.13,+ contravariant >=1.4 && <2,+ hashable >=1.2 && <2,+ ip >=1.7.8 && <2,+ iri:punycode,+ profunctors >=5.2 && <6,+ ptr >=0.16.1 && <0.17,+ template-haskell >=2.17 && <3,+ text >=2 && <3,+ text-builder ^>=1,+ th-lift >=0.8 && <0.9,+ th-lift-instances >=0.1.20 && <0.2,+ unordered-containers >=0.2 && <0.3,+ vector >=0.13 && <0.14,+ vector-builder >=0.3.4 && <0.4,+ vector-instances >=3.4 && <4,+ wide-word >=0.1.6 && <2, library punycode- hs-source-dirs: punycode+ hs-source-dirs: punycode default-language: Haskell2010 build-depends:- , base >=4.15 && <5- , bytestring >=0.10 && <0.13- , cereal >=0.5.8.3 && <0.6- , mtl >=2 && <3- , text >=2 && <3+ base >=4.13 && <5,+ bytestring >=0.10 && <0.13,+ cereal >=0.5.8.3 && <0.6,+ mtl >=2 && <3,+ text >=2 && <3, - exposed-modules: Data.Text.Punycode+ exposed-modules: Data.Text.Punycode other-modules: Data.Text.Punycode.Decode Data.Text.Punycode.Encode Data.Text.Punycode.Shared test-suite test- type: exitcode-stdio-1.0- hs-source-dirs: test- main-is: Main.hs- default-language: Haskell2010- default-extensions:- NoImplicitPrelude- NoMonomorphismRestriction- Arrows- BangPatterns- ConstraintKinds- DataKinds- DefaultSignatures- DeriveDataTypeable- DeriveFoldable- DeriveFunctor- DeriveGeneric- DeriveTraversable- EmptyDataDecls- FlexibleContexts- FlexibleInstances- FunctionalDependencies- GADTs- GeneralizedNewtypeDeriving- ImportQualifiedPost- LambdaCase- LiberalTypeSynonyms- MagicHash- MultiParamTypeClasses- MultiWayIf- OverloadedStrings- ParallelListComp- PatternGuards- PatternSynonyms- QuasiQuotes- RankNTypes- RecordWildCards- ScopedTypeVariables- StandaloneDeriving- TemplateHaskell- TupleSections- TypeFamilies- TypeOperators- UnboxedTuples-+ import: test+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ main-is: Main.hs build-depends:- , iri- , rerebase <2- , tasty >=0.12 && <2- , tasty-hunit >=0.9 && <0.11+ iri,+ rerebase <2,+ tasty >=0.12 && <2,+ tasty-hunit >=0.9 && <0.11,
library/Iri/CodePointPredicates/Core.hs view
@@ -1,6 +1,6 @@ module Iri.CodePointPredicates.Core where -import Data.Vector.Unboxed qualified as A+import qualified Data.Vector.Unboxed as A import Iri.Prelude hiding (Predicate, inRange, (&&&), (|||)) type Predicate =
library/Iri/CodePointPredicates/Rfc3987.hs view
@@ -114,7 +114,7 @@ module Iri.CodePointPredicates.Rfc3987 where import Iri.CodePointPredicates.Core-import Iri.CodePointPredicates.Rfc3986 qualified as A+import qualified Iri.CodePointPredicates.Rfc3986 as A import Iri.Prelude hiding (Predicate, inRange, (&&&), (|||)) scheme :: Predicate
library/Iri/Data/Functions.hs view
@@ -14,7 +14,7 @@ case hierarchy of AuthorisedHierarchy (Authority userInfo host port) path -> case userInfo of MissingUserInfo -> Right (HttpIri security host port path query fragment)- PresentUserInfo (User user) _ -> Left ("User Info is present")+ PresentUserInfo (User _) _ -> Left ("User Info is present") _ -> Left ("Not an authorised hierarchy") -- | Generalize an HTTP IRI to IRI
library/Iri/Data/Instances/Lift.hs view
@@ -2,12 +2,12 @@ module Iri.Data.Instances.Lift where -import Data.WideWord.Word128 qualified+import qualified Data.WideWord.Word128 import Iri.Data.Types import Iri.Prelude import Language.Haskell.TH.Lift import Language.Haskell.TH.Syntax-import Net.IPv6 qualified+import qualified Net.IPv6 fmap concat $ traverse deriveLift
library/Iri/Data/Instances/Show.hs view
@@ -2,10 +2,10 @@ module Iri.Data.Instances.Show where -import Data.Text qualified as B+import qualified Data.Text as B import Iri.Data.Types import Iri.Prelude-import Iri.Rendering.Text.Internal qualified as A+import qualified Iri.Rendering.Text.Internal as A instance Show Iri where show =
library/Iri/MonadPlus.hs view
@@ -1,8 +1,8 @@ module Iri.MonadPlus where import Iri.Prelude hiding (foldl)-import Ptr.ByteString qualified as ByteString-import Ptr.Poking qualified as Poking+import qualified Ptr.ByteString as ByteString+import qualified Ptr.Poking as Poking {-# INLINE foldl #-} foldl :: (MonadPlus m) => (a -> b -> a) -> a -> m b -> m a
library/Iri/Optics/Defs.hs view
@@ -1,13 +1,13 @@ module Iri.Optics.Defs where -import Data.Text.Encoding qualified as Text+import qualified Data.Text.Encoding as Text import Iri.Data import Iri.Optics.Basics-import Iri.Parsing.ByteString qualified as B-import Iri.Parsing.Text qualified as D+import qualified Iri.Parsing.ByteString as B+import qualified Iri.Parsing.Text as D import Iri.Prelude-import Iri.Rendering.ByteString qualified as A-import Iri.Rendering.Text qualified as C+import qualified Iri.Rendering.ByteString as A+import qualified Iri.Rendering.Text as C -- * Definitions by source
library/Iri/Parsing/Attoparsec/ByteString.hs view
@@ -8,21 +8,21 @@ where import Data.Attoparsec.ByteString hiding (try)-import Data.Attoparsec.ByteString.Char8 qualified as F-import Data.ByteString qualified as K-import Data.Text.Encoding qualified as B-import Data.Text.Encoding.Error qualified as L-import Data.Text.Punycode qualified as A-import Data.Vector qualified as S-import Iri.CodePointPredicates.Rfc3986 qualified as C+import qualified Data.Attoparsec.ByteString.Char8 as F+import qualified Data.ByteString as K+import qualified Data.Text.Encoding as B+import qualified Data.Text.Encoding.Error as L+import qualified Data.Text.Punycode as A+import qualified Data.Vector as S+import qualified Iri.CodePointPredicates.Rfc3986 as C import Iri.Data-import Iri.MonadPlus qualified as R-import Iri.PercentEncoding qualified as I+import qualified Iri.MonadPlus as R+import qualified Iri.PercentEncoding as I import Iri.Prelude hiding (foldl, hash)-import Net.IPv4 qualified as M-import Net.IPv6 qualified as N-import Text.Builder qualified as J-import VectorBuilder.MonadPlus qualified as E+import qualified Net.IPv4 as M+import qualified Net.IPv6 as N+import qualified TextBuilder as J+import qualified VectorBuilder.MonadPlus as E {-# INLINE percent #-} percent :: Parser Word8@@ -87,7 +87,7 @@ uri = labeled "URI" $ do parsedScheme <- scheme- colon+ _ <- colon parsedHierarchy <- hierarchy parsedQuery <- query parsedFragment <- fragment@@ -99,12 +99,12 @@ httpUri :: Parser HttpIri httpUri = labeled "HTTP URI" $ do- satisfy (\x -> x == 104 || x == 72)- satisfy (\x -> x == 116 || x == 84)- satisfy (\x -> x == 116 || x == 84)- satisfy (\x -> x == 112 || x == 80)+ _ <- satisfy (\x -> x == 104 || x == 72)+ _ <- satisfy (\x -> x == 116 || x == 84)+ _ <- satisfy (\x -> x == 116 || x == 84)+ _ <- satisfy (\x -> x == 112 || x == 80) secure <- satisfy (\b -> b == 115 || b == 83) $> True <|> pure False- string "://"+ _ <- string "://" parsedHost <- host parsedPort <- PresentPort <$> (colon *> port) <|> pure MissingPort parsedPath <- (forwardSlash *> path) <|> pure (Path mempty)@@ -169,26 +169,26 @@ ipV6 = do a <- F.hexadecimal- colon+ _ <- colon b <- F.hexadecimal- colon+ _ <- colon c <- F.hexadecimal- colon+ _ <- colon d <- F.hexadecimal- colon+ _ <- colon mplus ( do e <- F.hexadecimal- colon+ _ <- colon f <- F.hexadecimal- colon+ _ <- colon g <- F.hexadecimal- colon+ _ <- colon h <- F.hexadecimal return (N.fromWord16s a b c d e f g h) ) ( do- colon+ _ <- colon return (N.fromWord16s a b c d 0 0 0 0) ) @@ -252,7 +252,7 @@ fail "Unexpected decoding error" finish (builder, undecodedBytes, _) = if K.null undecodedBytes- then return (J.run builder)+ then return (J.toText builder) else fail (showString "UTF8 decoding: Bytes remaining: " (show undecodedBytes)) {-# INLINEABLE urlEncodedString #-}@@ -270,7 +270,7 @@ percentEncodedByte :: Parser Word8 percentEncodedByte = labeled "Percent-encoded byte" $ do- percent+ _ <- percent byte1 <- anyWord8 byte2 <- anyWord8 I.matchPercentEncodedBytes (fail "Broken percent encoding") return byte1 byte2
library/Iri/Parsing/Attoparsec/Text.hs view
@@ -17,20 +17,20 @@ where import Data.Attoparsec.Text hiding (try)-import Data.ByteString qualified as K-import Data.Text.Encoding qualified as B-import Data.Text.Encoding.Error qualified as L-import Data.Vector qualified as S-import Iri.CodePointPredicates.Rfc3987 qualified as C+import qualified Data.ByteString as K+import qualified Data.Text.Encoding as B+import qualified Data.Text.Encoding.Error as L+import qualified Data.Vector as S+import qualified Iri.CodePointPredicates.Rfc3987 as C import Iri.Data-import Iri.MonadPlus qualified as R+import qualified Iri.MonadPlus as R import Iri.Prelude-import Net.IPv4 qualified as M-import Net.IPv6 qualified as N-import Ptr.ByteString qualified as ByteString-import Ptr.Poking qualified as Poking-import Text.Builder qualified as J-import VectorBuilder.MonadPlus qualified as E+import qualified Net.IPv4 as M+import qualified Net.IPv6 as N+import qualified Ptr.ByteString as ByteString+import qualified Ptr.Poking as Poking+import qualified TextBuilder as J+import qualified VectorBuilder.MonadPlus as E {-# INLINE labeled #-} labeled :: String -> Parser a -> Parser a@@ -45,7 +45,7 @@ iri = labeled "IRI" $ do parsedScheme <- scheme- char ':'+ _ <- char ':' parsedHierarchy <- hierarchy parsedQuery <- query parsedFragment <- fragment@@ -57,9 +57,9 @@ httpIri :: Parser HttpIri httpIri = labeled "HTTP IRI" $ do- asciiCI "http"+ _ <- asciiCI "http" secure <- satisfy (\x -> x == 's' || x == 'S') $> True <|> pure False- string "://"+ _ <- string "://" parsedHost <- host parsedPort <- PresentPort <$> (char ':' *> port) <|> pure MissingPort parsedPath <- ((char '/') *> path) <|> pure (Path mempty)@@ -171,13 +171,13 @@ urlEncodedComponentText :: (Char -> Bool) -> Parser Text urlEncodedComponentText unencodedCharPredicate = labeled "URL-encoded component"- $ fmap J.run+ $ fmap J.toText $ R.foldl mappend mempty $ (J.text <$> takeWhile1 unencodedCharPredicate) <|> urlEncodedSequenceTextBuilder {-# INLINEABLE urlEncodedSequenceTextBuilder #-}-urlEncodedSequenceTextBuilder :: Parser J.Builder+urlEncodedSequenceTextBuilder :: Parser J.TextBuilder urlEncodedSequenceTextBuilder = labeled "URL-encoded sequence" $ do start <- progress (mempty, mempty, B.streamDecodeUtf8) =<< urlEncodedByte@@ -200,7 +200,7 @@ urlEncodedByte :: Parser Word8 urlEncodedByte = do- char '%'+ _ <- char '%' digit1 <- fromIntegral <$> hexadecimalDigit digit2 <- fromIntegral <$> hexadecimalDigit return (shiftL digit1 4 .|. digit2)
library/Iri/Parsing/ByteString.hs view
@@ -8,10 +8,10 @@ ) where -import Data.Attoparsec.ByteString qualified as B-import Data.ByteString qualified as ByteString+import qualified Data.Attoparsec.ByteString as B+import qualified Data.ByteString as ByteString import Iri.Data-import Iri.Parsing.Attoparsec.ByteString qualified as A+import qualified Iri.Parsing.Attoparsec.ByteString as A import Iri.Prelude parser :: B.Parser a -> ByteString -> Either Text a@@ -43,9 +43,9 @@ uriQuery :: ByteString -> Either Text Query uriQuery x = case ByteString.break (== 63) x of- (beforeQuestion, questionAndAfterQuestion) -> case ByteString.uncons questionAndAfterQuestion of+ (_, questionAndAfterQuestion) -> case ByteString.uncons questionAndAfterQuestion of Just (_, afterQuestion) -> case ByteString.break (== 35) afterQuestion of- (beforeHash, hashAndAfterHash) -> Right (Query beforeHash)+ (beforeHash, _) -> Right (Query beforeHash) Nothing -> Left "Does not start with a question mark"
library/Iri/Parsing/Text.hs view
@@ -14,9 +14,9 @@ ) where -import Data.Attoparsec.Text qualified as B+import qualified Data.Attoparsec.Text as B import Iri.Data-import Iri.Parsing.Attoparsec.Text qualified as A+import qualified Iri.Parsing.Attoparsec.Text as A import Iri.Prelude fromParser :: B.Parser a -> Text -> Either Text a
library/Iri/QuasiQuoter.hs view
@@ -6,10 +6,10 @@ ) where -import Data.Attoparsec.ByteString qualified as B-import Data.Attoparsec.Text qualified as C-import Iri.Parsing.Attoparsec.ByteString qualified as A-import Iri.Parsing.Attoparsec.Text qualified as D+import qualified Data.Attoparsec.ByteString as B+import qualified Data.Attoparsec.Text as C+import qualified Iri.Parsing.Attoparsec.ByteString as A+import qualified Iri.Parsing.Attoparsec.Text as D import Iri.Prelude hiding (exp) import Language.Haskell.TH.Quote import Language.Haskell.TH.Syntax
library/Iri/Rendering/ByteString.hs view
@@ -2,8 +2,8 @@ import Iri.Data import Iri.Prelude-import Iri.Rendering.Ptr.Poking qualified as A-import Ptr.ByteString qualified as F+import qualified Iri.Rendering.Ptr.Poking as A+import qualified Ptr.ByteString as F -- | Render as URI ASCII bytes uri :: Iri -> ByteString
library/Iri/Rendering/Ptr/Poking.hs view
@@ -10,19 +10,19 @@ ) where -import Data.ByteString qualified as ByteString-import Data.Text qualified as C-import Data.Text.Encoding qualified as A-import Data.Text.Punycode qualified as B-import Iri.CodePointPredicates.Core qualified as I-import Iri.CodePointPredicates.Rfc3986 qualified as I+import qualified Data.ByteString as ByteString+import qualified Data.Text as C+import qualified Data.Text.Encoding as A+import qualified Data.Text.Punycode as B+import qualified Iri.CodePointPredicates.Core as I+import qualified Iri.CodePointPredicates.Rfc3986 as I import Iri.Data import Iri.Prelude hiding (null, poke)-import Iri.Rendering.Ptr.Poke qualified as L-import Iri.Utf8CodePoint qualified as K-import Iri.Vector qualified as F-import Net.IPv4 qualified as D-import Net.IPv6 qualified as E+import qualified Iri.Rendering.Ptr.Poke as L+import qualified Iri.Utf8CodePoint as K+import qualified Iri.Vector as F+import qualified Net.IPv4 as D+import qualified Net.IPv6 as E import Ptr.Poking uri :: Iri -> Poking
library/Iri/Rendering/Text/Internal.hs view
@@ -2,55 +2,55 @@ import Iri.Data.Types import Iri.Prelude-import Iri.Rendering.TextBuilder.Internal qualified as A-import Text.Builder qualified as B+import qualified Iri.Rendering.TextBuilder.Internal as A+import qualified TextBuilder as B -- | Render as a Unicode IRI text iri :: Iri -> Text-iri = B.run . A.iri+iri = B.toText . A.iri -- | Render as a Unicode IRI text httpIri :: HttpIri -> Text-httpIri = B.run . A.httpIri+httpIri = B.toText . A.httpIri scheme :: Scheme -> Text-scheme = B.run . A.scheme+scheme = B.toText . A.scheme hierarchy :: Hierarchy -> Text-hierarchy = B.run . A.hierarchy+hierarchy = B.toText . A.hierarchy authority :: Authority -> Text-authority = B.run . A.authority+authority = B.toText . A.authority userInfo :: UserInfo -> Text-userInfo = B.run . A.userInfo+userInfo = B.toText . A.userInfo host :: Host -> Text-host = B.run . A.host+host = B.toText . A.host regName :: RegName -> Text-regName = B.run . A.regName+regName = B.toText . A.regName domainLabel :: DomainLabel -> Text-domainLabel = B.run . A.domainLabel+domainLabel = B.toText . A.domainLabel ipV4 :: IPv4 -> Text-ipV4 = B.run . A.ipV4+ipV4 = B.toText . A.ipV4 ipV6 :: IPv6 -> Text-ipV6 = B.run . A.ipV6+ipV6 = B.toText . A.ipV6 port :: Port -> Text-port = B.run . A.port+port = B.toText . A.port path :: Path -> Text-path = B.run . A.path+path = B.toText . A.path pathSegment :: PathSegment -> Text-pathSegment = B.run . A.pathSegment+pathSegment = B.toText . A.pathSegment query :: Query -> Text-query = B.run . A.query+query = B.toText . A.query fragment :: Fragment -> Text-fragment = B.run . A.fragment+fragment = B.toText . A.fragment
library/Iri/Rendering/TextBuilder/Internal.hs view
@@ -18,22 +18,22 @@ ) where -import Data.ByteString qualified as ByteString-import Data.Text qualified as C-import Data.Text.Encoding qualified as A-import Data.Text.Encoding.Error qualified as A-import Iri.CodePointPredicates.Core qualified as CorePredicates-import Iri.CodePointPredicates.Rfc3986 qualified as Rfc3986Predicates-import Iri.CodePointPredicates.Rfc3987 qualified as Rfc3987Predicates+import qualified Data.ByteString as ByteString+import qualified Data.Text as C+import qualified Data.Text.Encoding as A+import qualified Data.Text.Encoding.Error as A+import qualified Iri.CodePointPredicates.Core as CorePredicates+import qualified Iri.CodePointPredicates.Rfc3986 as Rfc3986Predicates+import qualified Iri.CodePointPredicates.Rfc3987 as Rfc3987Predicates import Iri.Data.Types import Iri.Prelude hiding (null)-import Iri.Utf8CodePoint qualified as K-import Iri.Vector qualified as F-import Net.IPv4 qualified as D-import Net.IPv6 qualified as E-import Text.Builder+import qualified Iri.Utf8CodePoint as K+import qualified Iri.Vector as F+import qualified Net.IPv4 as D+import qualified Net.IPv6 as E+import TextBuilder -iri :: Iri -> Builder+iri :: Iri -> TextBuilder iri (Iri schemeValue hierarchyValue queryValue fragmentValue) = scheme schemeValue <> char ':'@@ -47,7 +47,7 @@ (fragment fragmentValue) ) -httpIri :: HttpIri -> Builder+httpIri :: HttpIri -> TextBuilder httpIri (HttpIri (Security secure) hostValue portValue pathValue queryValue fragmentValue) = (if secure then string "https://" else string "http://") <> host hostValue@@ -56,11 +56,11 @@ <> prependIfNotNull (char '?') (query queryValue) <> prependIfNotNull (char '#') (fragment fragmentValue) -scheme :: Scheme -> Builder+scheme :: Scheme -> TextBuilder scheme (Scheme bytes) = text (A.decodeUtf8With A.lenientDecode bytes) -hierarchy :: Hierarchy -> Builder+hierarchy :: Hierarchy -> TextBuilder hierarchy = \case AuthorisedHierarchy authorityValue pathValue ->@@ -70,13 +70,13 @@ RelativeHierarchy pathValue -> path pathValue -authority :: Authority -> Builder+authority :: Authority -> TextBuilder authority (Authority userInfoValue hostValue portValue) = appendIfNotNull (char '@') (userInfo userInfoValue) <> host hostValue <> prependIfNotNull (char ':') (port portValue) -userInfo :: UserInfo -> Builder+userInfo :: UserInfo -> TextBuilder userInfo = \case PresentUserInfo (User user) password -> case password of@@ -84,82 +84,82 @@ MissingPassword -> userInfoComponent user MissingUserInfo -> mempty -userInfoComponent :: ByteString -> Builder+userInfoComponent :: ByteString -> TextBuilder userInfoComponent = urlEncodedBytesOrText Rfc3987Predicates.unencodedUserInfoComponent Rfc3986Predicates.unencodedUserInfoComponent -host :: Host -> Builder+host :: Host -> TextBuilder host = \case NamedHost value -> regName value IpV4Host value -> ipV4 value IpV6Host value -> ipV6 value -regName :: RegName -> Builder+regName :: RegName -> TextBuilder regName (RegName vector) = F.intercalate domainLabel (char '.') vector -domainLabel :: DomainLabel -> Builder+domainLabel :: DomainLabel -> TextBuilder domainLabel (DomainLabel x) = text x -ipV4 :: IPv4 -> Builder+ipV4 :: IPv4 -> TextBuilder ipV4 = text . D.encode -ipV6 :: IPv6 -> Builder+ipV6 :: IPv6 -> TextBuilder ipV6 = text . E.encode -port :: Port -> Builder+port :: Port -> TextBuilder port = \case- PresentPort value -> unsignedDecimal value+ PresentPort value -> decimal value MissingPort -> mempty -path :: Path -> Builder+path :: Path -> TextBuilder path (Path pathSegmentVector) = F.intercalate pathSegment (char '/') pathSegmentVector -pathSegment :: PathSegment -> Builder+pathSegment :: PathSegment -> TextBuilder pathSegment (PathSegment value) = urlEncodedBytesOrText Rfc3987Predicates.unencodedPathSegment Rfc3986Predicates.unencodedPathSegment value -query :: Query -> Builder+query :: Query -> TextBuilder query (Query value) = urlEncodedBytesOrText Rfc3987Predicates.unencodedQuery Rfc3986Predicates.unencodedQuery value -fragment :: Fragment -> Builder+fragment :: Fragment -> TextBuilder fragment (Fragment value) = urlEncodedBytesOrText Rfc3987Predicates.unencodedFragment Rfc3986Predicates.unencodedFragment value -urlEncodedBytesOrText :: CorePredicates.Predicate -> CorePredicates.Predicate -> ByteString -> Builder+urlEncodedBytesOrText :: CorePredicates.Predicate -> CorePredicates.Predicate -> ByteString -> TextBuilder urlEncodedBytesOrText unencodedPredicate1 unencodedPredicate2 bytes = case A.decodeUtf8' bytes of Right text -> urlEncodedText unencodedPredicate1 text Left _ -> urlEncodedBytes unencodedPredicate2 bytes -- | Apply URL-encoding to text-urlEncodedBytes :: CorePredicates.Predicate -> ByteString -> Builder+urlEncodedBytes :: CorePredicates.Predicate -> ByteString -> TextBuilder urlEncodedBytes unencodedPredicate = ByteString.foldl' ( \builder -> mappend builder . \byte -> if unencodedPredicate (fromIntegral byte)- then utf8CodeUnits1 byte+ then unicodeCodepoint (fromIntegral byte) else urlEncodedByte byte ) mempty -- | Apply URL-encoding to text-urlEncodedText :: CorePredicates.Predicate -> Text -> Builder+urlEncodedText :: CorePredicates.Predicate -> Text -> TextBuilder urlEncodedText unencodedPredicate = C.foldl' (\builder -> mappend builder . urlEncodedUnicodeCodePoint unencodedPredicate . ord) mempty -urlEncodedUnicodeCodePoint :: CorePredicates.Predicate -> Int -> Builder+urlEncodedUnicodeCodePoint :: CorePredicates.Predicate -> Int -> TextBuilder urlEncodedUnicodeCodePoint unencodedPredicate codePoint = if unencodedPredicate codePoint- then unicodeCodePoint codePoint+ then unicodeCodepoint codePoint else K.unicodeCodePoint codePoint@@ -168,19 +168,17 @@ (\b1 b2 b3 -> urlEncodedByte b1 <> urlEncodedByte b2 <> urlEncodedByte b3) (\b1 b2 b3 b4 -> urlEncodedByte b1 <> urlEncodedByte b2 <> urlEncodedByte b3 <> urlEncodedByte b4) -urlEncodedByte :: Word8 -> Builder-urlEncodedByte x =- case divMod x 16 of- (d1, d2) -> char '%' <> hexadecimalDigit d1 <> hexadecimalDigit d2+urlEncodedByte :: Word8 -> TextBuilder+urlEncodedByte x = char '%' <> hexadecimal x -prependIfNotNull :: Builder -> Builder -> Builder+prependIfNotNull :: TextBuilder -> TextBuilder -> TextBuilder prependIfNotNull prepended it =- if null it+ if isEmpty it then mempty else prepended <> it -appendIfNotNull :: Builder -> Builder -> Builder+appendIfNotNull :: TextBuilder -> TextBuilder -> TextBuilder appendIfNotNull appended it =- if null it+ if isEmpty it then mempty else it <> appended
test/Main.hs view
@@ -1,10 +1,10 @@ module Main where -import Iri.Parsing.ByteString qualified as D-import Iri.Parsing.Text qualified as F+import qualified Iri.Parsing.ByteString as D+import qualified Iri.Parsing.Text as F import Iri.QuasiQuoter-import Iri.Rendering.ByteString qualified as E-import Iri.Rendering.Text qualified as C+import qualified Iri.Rendering.ByteString as E+import qualified Iri.Rendering.Text as C import Test.Tasty import Test.Tasty.HUnit import Prelude