fjoppe / Legivel

F# Yaml 1.2 parser
https://fjoppe.github.io/Legivel
The Unlicense
60 stars 5 forks source link

Cannot parse DateTime if it only contains time #22

Closed Yaroshvitaliy closed 4 years ago

Yaroshvitaliy commented 4 years ago

Description

I am using Legivel v 0.4.1. Legivel cannot parse DateTime if it only contains a time part, e.g. "00:00:05".

In timestampToCanonical function I can only see two cases are handled:

  1. y-m-d format
  2. ISO8601 format

Repro steps

Legivel.Serialization.Deserialize<DateTime> "2020-3-25" // Success
Legivel.Serialization.Deserialize<DateTime> "2020-3-25 00:00:05" // Success
Legivel.Serialization.Deserialize<DateTime> "00:00:05" // Error

Expected behavior

DateTime parses with no error.

Actual behavior

DateTime parses with the following error: "Timestamp has incorrect format: 0:00:05".

Thanks

fjoppe commented 4 years ago

Hi,

The conversion from string to DateTime is based on the yaml timestamp tag. The yaml timestamp does not allow a conversion from time only.

Technically, there is no argument for this conversion to be impossible, as long as DateTime,Parse supports it. However, if I were to support this, I am leaving the yaml standard and loose interoperability with other yaml parsers (as long as they stick with the standard).

Maybe in this case, it is more suitable to implement your own customization to support this. The current code should provide enough example how to do this. Hopefully.

Yaroshvitaliy commented 4 years ago

Hi,

What about TimeSpan? How can I add a custom deserialization for TimeSpan? Thank you.

fjoppe commented 4 years ago

One thing in mind for Legivel was to make it extensible. I was doing my own project to test these ideas and discovered that Legivel wasn't enough open to do this. So no promises you can do this without troubles. Maybe you discover things that need to be opened up, I'd like to know..

These steps are required:

  1. You need a tag-resolution schema, to which you add your type, ie look here; A schema is defined like this, it does not matter in which module/namespace things are defined, you can specify the schema for the Parser.

  2. In the mapper, all supported types are defined in BuildInTryFindMappers, and specifically look at PrimitiveMappingInfo.

The tag-resolver is to detect the tag (ie timespan) based on Regex, check its validity. The mapper actually handles the conversion from text-to-type. The yaml mapper uses its own Schema.

You may probably check CustomDeserializeYaml to see how it is all wired together.