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

Expose tags and styles for sequences and mappings in Text.Libyaml #141

Merged
merged 10 commits into from
Jul 10, 2018

Conversation

gmorpheme
Copy link
Contributor

This makes tag and style information available on sequences and mappings as well as scalars (at the Text.Libyaml layer - it is not propagated anywhere else).

This would break code using Text.Libyaml because it adds extra fields into the Event data structure.

    EventSequenceStart !Tag !SequenceStyle !Anchor
    EventMappingStart !Tag !MappingStyle !Anchor

...however, I think this is the only sensible way to expose this information. It's definitely an omission at present (although it might very well be an intentional one!). The Tag data type includes MapTag and SeqTag but they'd never be used because tags on mappings and sequences are simply ignored.

data SequenceStyle = AnySequence | BlockSequence | FlowSequence
deriving (Show, Eq, Enum, Bounded, Ord, Data, Typeable)

data MappingStyle = AnyMapping | BlockMapping | FlowMapping
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the semantics for AnyMapping?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See slightly fuller note below. I understand AnyMapping / AnySequence express no preference as to style to emit (block being in most cases the default). The parser should always tell you block or flow.

Copy link
Contributor

@hvr hvr left a comment

Choose a reason for hiding this comment

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

This is a reasonable API change. I've just recently discovered the need to expose the flow/block style in HsYAML myself, see haskell-hvr/HsYAML@e93a4d4

Copy link
Owner

@snoyberg snoyberg left a comment

Choose a reason for hiding this comment

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

Definitely an oversight on my part, thanks for catching this. Can you additionally add a version bump, update the ChangeLog, and add @since comments to the Haddocks of newly added identifiers? It looks like this should be version 0.9.0.

@@ -77,6 +79,12 @@ data Style = Any
| PlainNoTag
deriving (Show, Read, Eq, Enum, Bounded, Ord, Data, Typeable)

data SequenceStyle = AnySequence | BlockSequence | FlowSequence
Copy link
Owner

Choose a reason for hiding this comment

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

Is there a case where AnySequence will come back from the parser, or is only useful for the emitter?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

AIUI from a reading of the libyaml source, AnySequence and AnyMapping are never produced by the parser (parser.c only references the flow and block constants). They correspond directly to the C enums and the Anys just express no preference as you'd expect. In reality, block is the default barring a few conditions:

e.g.

    if (emitter->flow_level || emitter->canonical
            || event->data.mapping_start.style == YAML_FLOW_MAPPING_STYLE
            || yaml_emitter_check_empty_mapping(emitter)) {
        emitter->state = YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE;
    }
    else {
        emitter->state = YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE;
    }

(I admit to some unease about the naming I've chosen here, particularly given this is an API change. Happy to accept alternative suggestions!)

stack.yaml Outdated
@@ -3,3 +3,6 @@ resolver: lts-11.10
flags:
yaml:
no-examples: false

docker:
enable: true
Copy link
Owner

Choose a reason for hiding this comment

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

Please remove this, Docker should not be the default for the repo.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops. Accidental, will do.

@@ -63,6 +63,12 @@ spec = do
it "count scalars with anchor" caseCountScalarsWithAnchor
it "count sequences with anchor" caseCountSequencesWithAnchor
it "count mappings with anchor" caseCountMappingsWithAnchor
it "count sequences with custom tag" caseCountSequenceTags
Copy link
Owner

Choose a reason for hiding this comment

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

Three cheers for new tests!

@gmorpheme
Copy link
Contributor Author

I've popped a @since on SequenceStyle and MappingStyle, bumped the package.yaml version and added a changelog entry.

bsToTag <$>
if ytag_len' == 0
then return Data.ByteString.empty
else packCStringLen (ytag', ytag_len')
Copy link
Owner

Choose a reason for hiding this comment

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

Given that under the surface the C code is just using strlen anyway to look for a null-terminating byte, is there a reason to use packCStringLen instead of packCString? It seems like the latter would allow us to simplify the changeset a bit.

@@ -77,6 +79,14 @@ data Style = Any
| PlainNoTag
deriving (Show, Read, Eq, Enum, Bounded, Ord, Data, Typeable)

-- @since 0.9.0
Copy link
Owner

Choose a reason for hiding this comment

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

This should be -- | @since 0.9.0 to make Haddock recognize it. Bonus points would be a short sentence explaining what the type is used for.

tagbs <-
if ytag_len' == 0
then return Data.ByteString.empty
else packCStringLen (ytag', ytag_len')
Copy link
Owner

Choose a reason for hiding this comment

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

Heh, doh, now I realize why you have it set up this way with the len, I did it that way in the first place. I think my claim that we can use packCString instead still applies, but your call on whether to include that now or if I try it separately after this gets merged.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ha. Yep - was trying to make minimal changes here but I didn't understand why the len approach was there. I'll kill it.

There's also some inconsistency between checking null ptrs in the helper C and in the Haskell but it kinda makes sense to unify null and "" for the case checking in the tag case.

@gmorpheme
Copy link
Contributor Author

gmorpheme commented Jul 10, 2018

Removed the len stuff for tag handling - should be functionally identical. We'd get into trouble anyway if a tag contained a null but that's illegal (at least in YAML 1.2 - http://yaml.org/spec/1.2/spec.html#ns-uri-char).

Haven't touched the len stuff with the value. Felt like a step too far for this change.

@gmorpheme
Copy link
Contributor Author

Oops - and have a failing test. Hold off...

@gmorpheme
Copy link
Contributor Author

Fixed.

Copy link
Owner

@snoyberg snoyberg left a comment

Choose a reason for hiding this comment

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

This is great stuff, thank you!

| EventMappingEnd
deriving (Show, Eq)

-- | Style for scalars - e.g. quoted / folded
Copy link
Owner

Choose a reason for hiding this comment

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

Thank you for cleanups like this 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, thank you for the whole library. 👍

@snoyberg snoyberg merged commit f01e81c into snoyberg:master Jul 10, 2018
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.

None yet

3 participants