Skip to content
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

WIP - An alternative approach to #31 (see also #33) #34

Closed
wants to merge 5 commits into from

Conversation

jeremyrsmith
Copy link
Collaborator

This approach moves the node handling to an object algebra. This allows for relatively easily adding configurable stuff that's able to change how various YAML types are handled as the need arises. One can even plug in their own algebra if they want to get nitty-gritty.

It also allows adding optional error accumulation, which is something that's always felt missing.

A nice thing here is by default we don't have to even check any configuration - only when a parser instance is configured do we change to ConfiguredAlg.

Also should be binary compatible (and yaml.parser.configure(...) is a nice way to get a configured parser!).

TODO: Add tests around error accumulation and such (coverage currently lacking)

This approach moves the node handling to an object algebra. This allows
for relatively easily adding configurable stuff that's able to change
how various YAML types are handled as the need arises. One can even plug
in their own algebra if they want to get nitty-gritty.

It also allows adding optional error accumulation, which is something
that's always felt missing.

A nice thing here is by default we don't have to even check any
configuration - only when a parser instance is configured do we change
to `ConfiguredAlg`.

Also should be binary compatible (and `yaml.parser.configure(...)` is a
nice way to get a configured parser!).

TODO: Add tests around error accumulation and such (coverage currently
lacking)
Copy link
Member

@travisbrown travisbrown left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it! I would like to get YAML-style booleans, ints, and floats, though—I know I could do this in my own NodeAlg implementation, but those seem uncontroversial enough to be the default.

}
}

final class AccumlatingAlg[A](base: NodeAlg[A]) extends NodeAlg[ValidatedNel[ParsingFailure, A]] {
Copy link
Member

@travisbrown travisbrown Jun 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick but is the missing u intentional?

final override def timestamp(node: ScalarNode): Json = if (!numericTimestamps) {
super.timestamp(node)
} else {
val constructor = new SafeConstructor.ConstructYamlTimestamp()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some part of me doesn't really like the idea of instantiating a constructor for every single timestamp node (especially since it involves a non-trivial amount of setting up its own internal state), but it probably doesn't matter much.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of that mutable internal state, I'm not sure what the other option is. You're not guaranteed that the algebra isn't being used from multiple threads.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately they don't expose just the timestamp parsing logic - otherwise we could bypass this allocation entirely.

Since the spec is pretty fixed, maybe it's worthwhile just duplicating their regexes and doing it internally here?

node.getValue.asScala.map {
nodeTuple => nodeTuple.getKeyNode match {
case keyNode: ScalarNode => keyNode.getValue -> any(nodeTuple.getValueNode)
case _ => throw ParsingFailure("Only string keys can be represented in JSON", null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The null isn't new but it makes me a little uncomfortable—so far in circe I haven't needed ParsingFailures that don't wrap an underlying exception, but this seems like a reasonable thing to want in this case, so maybe that member should be an Option.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could just give it an actual exception here. I don't think you should change ParsingFailure.

@codecov-io
Copy link

codecov-io commented Jun 10, 2017

Codecov Report

Merging #34 into master will decrease coverage by 27.56%.
The diff coverage is 50.57%.

Impacted file tree graph

@@             Coverage Diff             @@
##           master      #34       +/-   ##
===========================================
- Coverage     100%   72.43%   -27.57%     
===========================================
  Files           4        5        +1     
  Lines         106      156       +50     
  Branches        3        7        +4     
===========================================
+ Hits          106      113        +7     
- Misses          0       43       +43
Impacted Files Coverage Δ
src/main/scala/io/circe/yaml/parser/NodeAlg.scala 49.29% <49.29%> (ø)
src/main/scala/io/circe/yaml/parser/Parser.scala 56.25% <56.25%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update befb2b6...d899fc7. Read the comment docs.

@travisbrown
Copy link
Member

@jeremyrsmith What do you think about moving forward with this? I can live with the constructor construction.

Working on getting coverage back to 100%
@jeremyrsmith
Copy link
Collaborator Author

Apologies for letting this sit for multiple years. I think #31 solved the base issue – though I guess #33 was closed in favor of this PR (and I failed to shepherd this PR adequately 😞 to the point where it's beyond stale). Anyway, closing this one to avoid polluting the open issues; if anybody feels like it solves anything, feel free to reopen it and I'll try and figure out what I was doing with it 3 years ago and see if anything there is still applicable.

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

Successfully merging this pull request may close these issues.

3 participants