Hello everybody,
I’m currently working on an CLI application where I display a series of screens containing several candidates you can choose from. Like that :
> Create new tag
Existing tags
View timeline
I have a struct for the candidates containing the associated name and a function pointer to the function that needs to be triggered when that candidate is selected :
pub const FuzzyFinderCandidate = struct {
name: []const u8,
function: *const fn () void,
};
And then there is a struct for each screen where I have a list of FuzzyFinderCandidate
and the functions that need to be called according to the selected candidate :
pub const OperationScreen = struct {
// this is the struct that will actually handle the list of candidates
ff: FuzzyFinder = FuzzyFinder{},
pub fn init(self: *OperationScreen) !void {
var candidates = [_]FuzzyFinderCandidate{
.{ .name = "Create new tag", .function = goToCreateNewTagScreen },
.{ .name = "Existing tags", .function = goToExistingTagsScreen },
.{ .name = "View timeline", .function = goToViewTimelineScreen },
};
try self.ff.setCandidates(&candidates);
}
pub fn goToCreateScreen() void {
printer.print("Should go to tag creation screen\n", .{});
}
pub fn goToExistingTagsScreen() void {
printer.print("should go to existing tags screen\n", .{});
}
pub fn goToViewTimelineScreen() void {
printer.print("should go to view timeline screen\n", .{});
}
};
So far it works perfectly but the problem appears when I want to change the signature of the “callback functions”. For example to be able to access the fields of the screen struct :
pub fn goToExistingTagsScreen(self: *OperationScreen) void {
// need to do some stuff that require access to `self`
}
The function pointer in FuzzyFinderCandidate
now has an incorrect function signature and I’m not sure how to handle the situation since the signature will change with each different “screen” struct.
I could make a different type of “candidate” struct for each screen but it would only move the problem since the list of candidates is actually handled by the FuzzyFinder
struct that is the same for all the different screens.
The only solution I found was to make use of anytype
on the function pointer. But that is not an option anymore since anytype struct fields have been removed from the language.
It seems that the opaque
type could help with this situation but honestly I struggle to really understand how that works.
Any idea on the best way to handle this situation?