I'm working on some code that sanitizes and converts values of different types to strings. I thought it would be a good idea to wrap the sanitized string in a struct to have some type safety. Ideally it should not be possible to create this type without going through the sanitizing functions.

The problem I have is that I would like these functions to push up the allocation decision to the caller. Internally these functions use formattedWrite. I thought the natural design would be that the sanitize functions take an output range and pass that to formattedWrite.

Here's a really simple example:

import std.stdio : writeln;

struct Range
{
    void put(char c)
    {
        writeln(c);
    }
}

void sanitize(OutputRange)(string value, OutputRange range)
{
    import std.format : formattedWrite;
    range.formattedWrite!"'%s'"(value);
}

void main()
{
    Range range;
    sanitize("foo", range);
}

The problem now is that the data is passed one char at the time to the range. Meaning that if the user implements a custom output range, the user is in full control of the data. It will now be very easy for the user to make a mistake or manipulate the data on purpose. Making the whole idea of the sanitized type pointless.

Any suggestions how to fix this or a better idea?

--
/Jacob Carlborg

Reply via email to