-
Notifications
You must be signed in to change notification settings - Fork 145
Implemented TH splices for validated ByteString literals #712
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
70f1a6a
to
b53c921
Compare
@Bodigrim I don't understand what's going on with CI. Any help appreciated. |
@vdukhovni no idea tbh. Maybe something changed under the hood, either in runner images or in the haskell action. |
I have very little experience tuning GitHub CI. Any chance someone can help? |
It seems it was an intermittent failure with https://github.com/haskell-actions/setup. I don't think you need to touch CI setup in this PR. |
Thanks, indeed most of the problems appear to have been transient. I reverted the CI changes, and the only failure so far is with Otherwise, no issues. So I think I'm done, unless you'd prefer to name the two functions differently. The names |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
I would prefer more explicit names: something like literalFromAscii
(or literalFromChar8
) and literalFromHex
Many thanks for the prompt review! I'm about to push a fixup for all the nits, and what remains then is to reach consensus on the splice names. Of the above I prefer |
Yes the type and |
c5906d9
to
28a0cb6
Compare
83cf073
to
2f5671a
Compare
import Data.Bits ((.&.)) | ||
import Data.Bits ((.|.), (.&.), complement, shiftL) | ||
import Data.Char (ord) | ||
import Data.Foldable (foldr') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The unqualified foldr'
briefly confused me. (Actually, why are these quote-generators defined in D.B.Internal.Type
instead of the exposed Data.ByteString
?)
Data/ByteString/Internal/Type.hs
Outdated
-- > ehloCmd :: ByteString | ||
-- > ehloCmd = $$(literalFromChar8 "EHLO") | ||
-- | ||
literalFromChar8 :: String -> THLift ByteString |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I respect the idea of using a type synonym here, but (with recent GHCs) it expands to a higher-rank type, which is different from the type we would otherwise have given it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The alternative to just repeat the whole function with a different type signature, or use CPP.
Is that necessary? I've not run into any issues with using the splice in GHC 9.12. Is there a problem with 9.14?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Take a look at how template-haskell-lift
shims around this: https://gitlab.haskell.org/ghc/template-haskell-lift/-/blob/main/src/Language/Haskell/TH/Lift.hs?ref_type=heads#L40
It's currently unreleased, but I'll try to publish this library in the next few weeks.
It means we can just write Qoute m => ... -> Code m a
and it will turn into the correct thing for all versions of GHC without higher-rank types, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've adopted that approach.
literalFromChar8 "" = [||empty||] | ||
literalFromChar8 s = case foldr' op (Octets 0 []) s of | ||
Octets n ws -> liftTyped (unsafePackLenBytes n ws) | ||
Hichar i w -> liftCode $ fail $ "non-octet character '\\" ++ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@TeofilC Would this liftCode $ fail $ ...
stuff require any adjustments to your template-haskell-lift
plans?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the headsup. This should be fine.
op :: Char -> S2W -> S2W | ||
op (fromIntegral . fromEnum -> !(w :: Word)) acc | ||
| w <= 0xff = case acc of | ||
Octets i ws -> Octets (i + 1) (fromIntegral w : ws) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(i+1)
can overflow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would require that the input string length be greater than maxBound @Int
, and the consequence is just an incorrect report of the problem offset. I suspect this does not warrant work-arounds.
thLiteral :: Quote m => String -> Code m ByteString thHexLiteral :: Quote m => String -> Code m ByteString The former rejects inputs with non-octet code points above 0xFF. The latter rejects odd-length inputs or inputs with characters other than non-hexadecimal digits.
Henry Sylvain review fixups
Andrew Lelechenko review fixes
3626e62
to
8b3189d
Compare
…literals tweak TH type signatures
8b3189d
to
d8c2d02
Compare
The former rejects inputs with non-octet code points above 0xFF. The latter rejects odd-length inputs or inputs with characters other than non-hexadecimal digits.