v icon indicating copy to clipboard operation
v copied to clipboard

error: cannot convert 'struct string' to 'struct array'

Open fnetX opened this issue 3 years ago • 8 comments

V version: V 0.2.2 0da827f.8caabf0 OS: linux, Debian GNU/Linux bullseye/sid

What did you do? This is the minimum example I could reproduce this with, you can also find it over at https://codeberg.org/eventbike/vlang_plg/src/branch/main/2021-04-08_cannot_describe

module main

import vweb

pub struct Project {
	vweb.Context
}

fn main() {
	vweb.run<Project>(9080)
}

struct ExampleStruct {
	example int
}

pub fn (mut app Project) request_raw_2() vweb.Result {
	stuff := []ExampleStruct{}
	return app.request_raw(stuff)
}

pub fn (mut app Project) request_raw(foo []ExampleStruct) vweb.Result {
	return $vweb.html()
}

What did you expect to see? request_raw_2 can be used to return request_raw with some different properties

What did you see instead?

/tmp/v/2021-04-08_cannot_describe.5642974674744139927.tmp.c:21676: error: cannot convert 'struct string' to 'struct array'
builder error: 
==================
C error. This should never happen.

fnetX avatar Apr 08 '21 00:04 fnetX

When you create a function like this:

pub fn (mut app Project) request_raw(foo []ExampleStruct) vweb.Result {
	return $vweb.html()
}

It is being registered as a route, and the arguments are URL path parameters (e.g. /:id), so it is expecting a string.

The bug here is not warning about the invalid usage.

mcastorina avatar Apr 08 '21 16:04 mcastorina

Okay, thanks for pointing this out. It worked well for my other functions and I used it heavily in my recent projects, but only with int and string so far.

It's super useful to alias functions this way and prepare content for a common response. Since templating isn't really mature yet, the only workaround would be creating the same template over and over again for different functions that serve the same template I fear :confused:

I will try registering them on a different struct that passes the necessary information to them. This sounds like an option offeriing similar convenience, but I somehow doubt this works.

fnetX avatar Apr 08 '21 16:04 fnetX

V has $tmpl for templating. I believe it's the same used with $vweb.html() except you can pass a filename.

https://github.com/vlang/v/blob/master/doc/docs.md#tmpl-for-embedding-and-parsing-v-template-files

mcastorina avatar Apr 10 '21 15:04 mcastorina

I think the functions are different in terms of escaping and tab stripping, but thank you for the hint, I'll try and see if it solves the problem I just ran into.

Please note, that my general use case not only involves template files. I might also want to pass a struct to a function which then decides to return a 404. Handling this via Optionals or custom error checking is much more difficult than just passing the data to another vweb function (works for now only with strings and ints).

fnetX avatar Apr 10 '21 17:04 fnetX

Hm.. a method is determined as a route if it's a method of App and it returns a vweb.Result.

With that in mind, you should be able to use a helper function like so:

fn helper_func(mut a App, foo []ExampleStruct) vweb.Result { /* ... */ }

The added benefit is you also aren't exposing a /helper_func route in your service.

mcastorina avatar Apr 10 '21 17:04 mcastorina

By the way, doing so is now causing "out of memory" errors during runtime (without crashing, but also without useful results). Was a change in V causing this, even old commits don't work any more.

Looks, like I have to use your proposal then ...

fnetX avatar Apr 21 '21 19:04 fnetX

I still think those helper functions that are registered on the Context struct are worth a consideration, it looks better than passing it. And you could differentiate between public and private functions for vweb routes.

fnetX avatar Apr 21 '21 19:04 fnetX

Still an issue.

medvednikov avatar Jul 22 '22 21:07 medvednikov

Thank you. @yuyi98

fnetX avatar Oct 25 '22 09:10 fnetX

Now I can finally go on with my project :joy:

fnetX avatar Oct 25 '22 09:10 fnetX