RejectedSoftware Forums

Sign up

Struct as parameter

Good day.

There is a simple struct:

struct User {
    long id;
    string family;
    string name;
    string surname;
    bool active;
    string login;
    string password;
    RoleEnum role;
}

enum RoleEnum { admin = 1, user };

I want to fill this struct from web form:

section(class="wrap-form")
        form(action="user", method="POST", class="user-form")
            div(class="field")
                label(for="family") Family
                input(type="text", name="family", id="family", value="#{user.family}")
            div(class="field")
                label(for="name") Name
                input(type="text", name="name", id="name", value="#{user.name}")
            div(class="field")
                label(for="surname") Surname
                input(type="text", name="surname", id="surname", value="#{user.surname}")
            div(class="field")
                label(for="active") Is active?
                - if (user.active)
                    input(type="checkbox", name="active", id="active", checked)
                - else
                    input(type="checkbox", name="active", id="active")
            div(class="field")
                label(for="login") Login
                input(type="text", name="login", id="login", value="#{user.login}")
            div(class="field")
                label(for="role") Role
                select(size="1", name="role", id="role")
                    - import std.traits : EnumMembers;
                    - import model.user : RoleEnum;
                    - foreach(role; [EnumMembers!RoleEnum])
                        - if (role == user.role)
                            option(selected="true") #{role}
                        - else
                            option #{role}
            input(type="hidden", name="password", value="")
            
            div(class="field")
                button(type="submit") Save

If I use separate fields, it works.

auto router = new URLRouter;
router.registerWebInterface(new UserController);

...

class UserController
...
public void postUser(string family, string name, string surname, string login, bool active, string password, RoleEnum role)

But if I use more convinient form, then compiler produces an error:

public void postUser(User user)

../../../../.dub/packages/vibe-d-0.8.5/vibe-d/web/vibe/web/common.d(889,29): Error: template vibe.web.common.readFormParamRec cannot deduce function from argument types !()(HTTPServerRequest, string, string, bool, NestedNameStyle, ParamError), candidates are:
../../../../.dub/packages/vibe-d-0.8.5/vibe-d/web/vibe/web/common.d(718,21): readFormParamRec(T)(scope HTTPServerRequest req, ref T dst, string fieldname, bool required, NestedNameStyle style, ref ParamError err)
../../../../.dub/packages/vibe-d-0.8.5/vibe-d/web/vibe/web/web.d(956,40): Error: template instance vibe.web.common.readFormParamRec!(User) error instantiating
../../../../.dub/packages/vibe-d-0.8.5/vibe-d/web/vibe/web/web.d(207,34): instantiated from here: handleRequest!("postUser", postUser, UserController)
source/app.d(49,32): instantiated from here: registerWebInterface!(UserController, cast(MethodStyle)5)

What I must to do to use public void postUser(User user) instead of individual parts of struct?

I will be grateful for both the documentation and for the advice.

Re: Struct as parameter

On Sat, 28 Sep 2019 14:03:51 GMT, Vitaly Livshic wrote:

(...)
But if I use more convinient form, then compiler produces an error:

public void postUser(User user)

../../../../.dub/packages/vibe-d-0.8.5/vibe-d/web/vibe/web/common.d(889,29): Error: template vibe.web.common.readFormParamRec cannot deduce function from argument types !()(HTTPServerRequest, string, string, bool, NestedNameStyle, ParamError), candidates are:
(...)

What I must to do to use public void postUser(User user) instead of individual parts of struct?

I will be grateful for both the documentation and for the advice.

I tried to reproduce the error, but it works for me both for vibe.d 0.8.5 and 0.8.6. Which compiler and compiler version are you using?

For this to work properly, in the HTML form, you should use "user_id", "user_family" etc. as field names. By annotating UserController with @nestedNameStyle(NestedNameStyle.d) you can also switch this to "user.id".