Skip to content

Text.Parsing.Parser.ArrayBuffer #88

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

Closed
jamesdbrock opened this issue Feb 20, 2020 · 7 comments
Closed

Text.Parsing.Parser.ArrayBuffer #88

jamesdbrock opened this issue Feb 20, 2020 · 7 comments

Comments

@jamesdbrock
Copy link
Member

I want to parse the raw Uint8 bytes of a Javascript ArrayBuffer. You know, like the ByteString instance for Megaparsec Streams, or Data.Attoparsec.ByteString.

Is there a good way to do this in Purescript? I can't find it. If this doesn't exist, maybe we could add a new module to purescript-parsing called Text.Parsing.Parser.ArrayBuffer? It seems like purescript-parsing was designed to be extended in this way.

This module would be a peer of Text.Parsing.Parser.String and Text.Parsing.Parser.Token, and similarly constructed.

Or maybe this would be better as a separate library, since it would add some new dependencies:

https://pursuit.purescript.org/packages/purescript-arraybuffer
https://pursuit.purescript.org/packages/purescript-arraybuffer-types

Thoughts?

@jamesdbrock
Copy link
Member Author

jamesdbrock commented Feb 21, 2020

The fact that getUint8 is an Effect function might complicate this.

I would probably just unsafePerformEffect in the implementation and warn users not to mutate the ArrayBuffer while parsing.

@garyb
Copy link
Member

garyb commented Feb 21, 2020

I don't think the Effect is a problem, you can use the m part of ParserT to handle that. Something along the lines of:

import Control.Monad.State (get, modify_)
import Control.Monad.Trans.Class (lift)
import Data.ArrayBuffer.DataView (getUint8)
import Data.ArrayBuffer.Types (DataView)
import Data.Maybe (Maybe(..))
import Data.UInt (UInt)
import Effect.Class (class MonadEffect, liftEffect)
import Text.Parsing.Parser (ParseState(..), ParserT, fail)
import Text.Parsing.Parser.Pos (Position(..))

uint8   m. MonadEffect m  ParserT DataView m UInt
uint8 = do
  ParseState input (Position { column }) _ <- get
  lift (liftEffect (getUint8 input column)) >>= case _ of
    Nothing → fail "Unexpected EOF"
    Just i → do
      modify_ \(ParseState _ position _) ->
        ParseState input (Position { line: 0, column: column + 1 }) true
      pure i

I haven't tested that, so it might not behave quite right, but it compiles and shouldn't be too far off.

The Position hard coded into ParserT isn't really ideal for this purpose 😕, hence the fixed line: 0.

@jamesdbrock
Copy link
Member Author

Good idea. I'll take a shot at a PR for this.

@jamesdbrock
Copy link
Member Author

https://pursuit.purescript.org/packages/purescript-arraybuffer is not a purescript-contrib library, is it okay for purescript-parsing to depend on it?

@jamesdbrock
Copy link
Member Author

purescript-arraybuffer is really nice because it handles endianness.

@garyb
Copy link
Member

garyb commented Feb 22, 2020

Hmm, good point - we try to avoid extra-contrib dependencies unless the library is maintaned by one of us in contrib/core (in the past we've had dependencies that end up blocking libraries that need updates).

Maybe this would be better off as a new library that depends on -arraybuffer and -parsing. I'd be happy to add a link to it in the readme here to help others find it, if you put something together.

@jamesdbrock
Copy link
Member Author

Also transitively depends on non-contrib library https://pursuit.purescript.org/packages/purescript-typelevel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants