v
v copied to clipboard
error: cannot convert 'struct string' to 'struct array'
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.
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.
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.
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
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).
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.
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 ...
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.
Still an issue.
Thank you. @yuyi98
Now I can finally go on with my project :joy: