#Define type of struct field at compile time?

1 messages · Page 1 of 1 (latest)

frank orchid
#
pub const Content = struct {
    here: T
}

and I am curious if there is a way to instantiate a Content struct with a user defined struct T? So if the user had a struct called Jake where Jake is

pub const Jake = struct {
   age: u8,
   friend: u8
}

I would like a Content struct so that i could do content.here.age

sharp patrol
#
pub fn Content(comptime T: type) type {
    return struct {
        here: T
    };
}

var jake_content = Content(Jake){ .here = .{ .age = 42, .friend = 255 } };
frank orchid
#

This is the challenge im having trying to apply your solution to my current project

#

Sorry - im on my phone and can’t format the code block

#

const std = @import("std");
const headers = @import("headers.zig");
const start_line = @import("start_line.zig");

pub const Message = struct { start_line: start_line.Type, headers: headers.Headers, body: ??? };

pub fn Build(start_line: start_line.Type, headers: headers.Headers, comptime Body: type) ??? {
return struct { start_line: start_line.Type, headers: headers.Headers, body: Body };
}

#

What do I do for the ???

#

I guess how do you define a type (in my case a struct) where a field type can be set yo anything?

inland pecan
#

you can turn Message into a function like mike suggested

#

the second ???, put Message(Body)

#

then in the return expression, put Message(Body){ .start_line = ... }

sharp patrol
#

++ gracefu that's what I'd do
with generics you kind of have to make any builder/creation types and functions generic up until the point where you're able to specify the concrete type

#

if the part of code that knows what the concrete type of Body should be doesn't share a call graph ancestor with Builder, but you do have a finite set of types it could be, then maybe what you need is to make that member a tagged union

#

another option is type erasure, but that's a massive leap forward in complexity--only worth pursuing if the set of types for Body is effectively boundless and you can't make generics work because you can't get a consistent comptime call tree from point of instantiation to point of use

frank orchid
#

I’ll have to explore this more - body can be any user defined struct though so maybe I need to look into type erasure?

sharp patrol
#

Do you need to support arbitrarily changing the type of Body for the same Message object, or can you have users work with a Message(SomeBodyType)?

I really wanna emphasize that type erasure can be a giant PITA, especially if you need to be able to serialize messages since std.json doesn't have a way to deal with type erased fields