how to parse a string into a phobos datatype with additional logic

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Apr 7 11:29:19 PDT 2016


On Thursday, April 07, 2016 07:45:06 yawniek via Digitalmars-d-learn wrote:
> what is the way one is supposed to parse e.g. a
> double of unixtime (as delived by nginx logs) into a SysTime?
>
> currently i'm creating a wrapper struct around SysTime with alias
> this as:
>
> https://gist.github.com/yannick/6caf5a5184beea0c24f35d9d4a4c7783
>
> really ugly imho.
>
> is there a better way to do this?

Functions like format, to, etc. all use toString and constructors when
dealing with conversions to and from string. There is no way to provide a
custom conversion function for them to use with a type instead of what's
built into the type. So, if you want this to be automatic as you pass the
type around, then AFAIK, your solution is really the only solution.
Certainly, you can create a custom conversion function and use it in your
own code, but nothing else is going to know about it or use it.

But honestly, I don't see how we even _could_ make it possible to provide a
custom conversion function except for having another argument (either an
alias template argument, or a function argument which is a delegate), and
that would mean that everything that might use such a conversion function
would have to accept it. That might work for something like std.conv.to, but
once you're dealing with something like the CSVParser, what's it going to
do? Have every function that might use such a conversion take a template
argument for the conversion function so that it could pass it on to
std.conv.to or std.conv.parse? And what of code that then uses CSVParser?
Does it need to then accept and pass on such conversion functions? And what
if you need more than one conversion function, because you're dealing with
multiple types that you want to convert differently than normal? I just
don't see how that scales.

Really, as annoying as it may be to wrap the type in another type just to
get the conversion, it's by far the cleanest way to do it. I just don't see
how we even _could_ do in a sane way that involved any kind of free
function. That would be like trying to arbitrarily add a constructor or
overloaded operator to a type and have all other code magically use it,
which is pretty much impossible given D's compilation model (e.g. the type
could be being used in a library that was already compiled when you try and
use it in your program), and how on earth would you deal with conflicts? If
two different modules both tried to add a constructor or overloaded operator
to a type, and those conflicted, how would other code know which to use -
especially when this is supposed to be invisible to them?

So, while I understand your frustration, I just don't see any other sane way
to approach this problem than what you've done. Putting it all in a wrapper
type encapsulates it in a way that it can actually work, whereas the other
options get messy really fast if they're possible at all.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list