Thread overview
Using output-range overloads of SysTime.toISO{Ext}String with formatting code
Jul 07, 2019
drug
Jul 08, 2019
Digital Mars
Jul 09, 2019
Mitacha
July 07, 2019
Hello folks,

Is there an idiomatic/intended way to use the output-range taking overloads of SysTime.toISOString and toISOExtString with stuff like `writeln` and `format`, as opposed to explicitly generating an output range to stdout or a string, and passing that to these methods?

I'm a bit unfamiliar with exactly all the ins and outs of the more recent output-range-based formatting design, but what I'm interested in whether it's possible to do something like `writefln!"%s"(now.toISOExtString)` and have it automatically use the output range overload rather than allocating a new string instance.

If that exact syntax doesn't work, is there anything almost as convenient?

Thanks & best wishes,

     -- Joe
July 07, 2019
07.07.2019 17:49, Joseph Rushton Wakeling пишет:
> it's possible to do something like `writefln!"%s"(now.toISOExtString)` and have it automatically use the output range overload rather than allocating a new string instance.

This is exactly how it is intended to work: https://run.dlang.io/is/ATjAkx

July 08, 2019
On Sunday, 7 July 2019 at 20:12:30 UTC, drug wrote:
> 07.07.2019 17:49, Joseph Rushton Wakeling пишет:
>> it's possible to do something like `writefln!"%s"(now.toISOExtString)` and have it automatically use the output range overload rather than allocating a new string instance.
>
> This is exactly how it is intended to work: https://run.dlang.io/is/ATjAkx

Thanks for taking the time to answer, but I don't think this really addresses my question.

Your example shows a struct with `toString` overloads.  However, SysTime.toISOExtString does not work like this: it is a method with two explicit overloads, one of which just returns a newly allocated `string`, the other of which returns nothing but accepts an output range as input:
https://dlang.org/phobos/std_datetime_systime.html#.SysTime.toISOExtString

I want to know if there's an easy way to work with that in `format` and `writefln` statements.

Note that while SysTime does also have `toString` methods, these give no control over the kind of datetime string that results:
https://dlang.org/phobos/std_datetime_systime.html#.SysTime.toString

Since I explicitly need the extended ISO format, I need to use `toISOExtString` directly.
July 08, 2019
08.07.2019 13:38, Joseph Rushton Wakeling пишет:
> 
> Thanks for taking the time to answer, but I don't think this really addresses my question.
> 
> Your example shows a struct with `toString` overloads.  However, SysTime.toISOExtString does not work like this: it is a method with two explicit overloads, one of which just returns a newly allocated `string`, the other of which returns nothing but accepts an output range as input:
> https://dlang.org/phobos/std_datetime_systime.html#.SysTime.toISOExtString
> 
> I want to know if there's an easy way to work with that in `format` and `writefln` statements.
> 
> Note that while SysTime does also have `toString` methods, these give no control over the kind of datetime string that results:
> https://dlang.org/phobos/std_datetime_systime.html#.SysTime.toString
> 
> Since I explicitly need the extended ISO format, I need to use `toISOExtString` directly.
Sorry that my answer wasn't thoughtful.

I guess that there is no way to have `writeln` automatically use the output range overload instead of allocating one. You need somehow to provide the output range to `toISOExtString` explicitly because `writeln` outputs the return of `toISOExtString` and have no ability to use specific overload. That is compiler calls `toISOExtString` and then passes its return to `writeln`. Probably library solution isn't possible in this case. Workaround is using own wrapper to provide output range to `toISOExtString`.
July 09, 2019
On Monday, 8 July 2019 at 12:53:18 UTC, Digital Mars wrote:
> 08.07.2019 13:38, Joseph Rushton Wakeling пишет:
>> [...]
> Sorry that my answer wasn't thoughtful.
>
> I guess that there is no way to have `writeln` automatically use the output range overload instead of allocating one. You need somehow to provide the output range to `toISOExtString` explicitly because `writeln` outputs the return of `toISOExtString` and have no ability to use specific overload. That is compiler calls `toISOExtString` and then passes its return to `writeln`. Probably library solution isn't possible in this case. Workaround is using own wrapper to provide output range to `toISOExtString`.

I've managed to make it work using 'alias this' and wrapper struct.
https://run.dlang.io/is/3SMEFZ
It's not an elegant solution, there could be a better way to do this.
July 09, 2019
On Monday, 8 July 2019 at 12:53:18 UTC, Digital Mars wrote:
> I guess that there is no way to have `writeln` automatically use the output range overload instead of allocating one. You need somehow to provide the output range to `toISOExtString` explicitly because `writeln` outputs the return of `toISOExtString` and have no ability to use specific overload. That is compiler calls `toISOExtString` and then passes its return to `writeln`. Probably library solution isn't possible in this case. Workaround is using own wrapper to provide output range to `toISOExtString`.

This is pretty much what I'd concluded myself, but I wanted to check to make sure there wasn't some clever option I didn't know about.  A helper function with wrapper struct seems the obvious way forward.
July 09, 2019
On Tuesday, 9 July 2019 at 08:51:59 UTC, Mitacha wrote:
> I've managed to make it work using 'alias this' and wrapper struct.
> https://run.dlang.io/is/3SMEFZ
> It's not an elegant solution, there could be a better way to do this.

Yea, a wrapper struct with custom `toString` seems the most obvious way forward.  No need to bother with `alias this`, though, since one only needs the wrapper struct at the point where one wants to format the datetime info.  A wrapper struct like this:

    struct ISOExtSysTime
    {
        private SysTime systime;

        public void toString (Output) (ref Output output)
            if (isOutputRange!(Output, char))
        {
            this.systime.toISOExtString(output);
        }
    }

allows easy usage along the lines of:

    writefln!"%s"(ISOExtSysTime(sys_time));

... and one could easily write a small factory function to shorten the code if needed.