Skip to content

[Enhancement] Allow attributes, like format_read, to have inlined code #116

Open

Description

@BobSmun

Currently, various attributes like format_read require a string containing a function name as the argument. A lot of the time, these functions seem to end up being a simple one-liner.

// == current ==
struct DATE
{
    u16 year;
    u8 month;
    u8 day;
}
[[
    format_read("read_DATE"),
    transform("transform_DATE"),
    ...
]];
fn read_DATE(auto v)
{
    return std::format("{}-{}-{}", v.year, v.month, v.day);
};
fn transform_DATE(auto v)
{
    return (v.year * 10000) + (v.month * 100) + v.day;
};

This adds a decent amount of boilerplate overhead, making the underlying data format specification a little more difficult to read (due to tool integration 'noise'). Although the function could be moved to a different part of the pattern file, to somewhat separate data format from integration, the function would then no longer be co-located with the data it's operating on.

I feel things could be cleaner / clearer, if the contents of that function were optionally able to be inlined. This also avoids needing the pattern creator to make sure the function is uniquely named, as well as having to access the data through a (named) parameter.

As a first pass suggestion, inlining simple one-liners could look like:

// == proposed ==
struct DATE
{
    u16 year;
    u8 month;
    u8 day;
}
[[
    format_read(std::format("{}-{}-{}", year, month, day)),
    transform((year * 10000) + (month * 100) + day),
    ...
]];

Activity

  1. BobSmun commented on Aug 10, 2024

    @BobSmun
    ContributorAuthor

    Multi-line functions might also be able to be supported, if we consider the concept of lambdas and borrowing some of its formatting. We might go from something that looks like:

    // == current (with a more complicated function example) ==
    struct DATE
    {
        u16 year;
        u8 month;
        u8 day;
    }
    [[
        format_read("read_DATE"),
        transform("transform_DATE"),
        format_write("write_DATE"),
        ...
    ]];
    fn read_DATE(auto v)
    {
        return std::format("{}-{}-{}", v.year, v.month, v.day);
    };
    fn transform_DATE(auto v)
    {
        return (v.year * 10000) + (v.month * 100) + v.day;
    };
    fn write_DATE(str v)
    {
        //not many examples of write functions, let's assume...
        u64 parsed = std::string::parse_int(v, 0);
    
        DATE result;
        result.year = parsed / 10000;
        result.month = (parsed / 100) % 100;
        result.day = parsed % 100;
        return result;
    };

    to something perhaps like:

    // == proposed (with a more complicated function example) ==
    struct DATE
    {
        u16 year;
        u8 month;
        u8 day;
    }
    [[
        format_read(std::format("{}-{}-{}", year, month, day)),
        transform((year * 10000) + (month * 100) + day),
        format_write([](str v)
            {
                //not many examples of write functions, let's assume...
                u64 parsed = std::string::parse_int(v, 0);
    
                DATE result;
                result.year = parsed / 10000;
                result.month = (parsed / 100) % 100;
                result.day = parsed % 100;
                return result;
            }),
        ...
    ]];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions