feat(element/input): make accept event agnostic to u8 and u21 slices
Some checks failed
Zig Project Action / Lint, Spell-check and test zig project (push) Failing after 50s
Some checks failed
Zig Project Action / Lint, Spell-check and test zig project (push) Failing after 50s
There are now comptime checks in place an the corresponding triggered event will be automatically converted to the correct type to support simple ascii strings (`[]u8`) or utf-8 strings (`[]u21`).
This commit is contained in:
@@ -127,10 +127,7 @@ pub fn main() !void {
|
||||
.key => |key| if (key.eql(.{ .cp = 'c', .mod = .{ .ctrl = true } })) app.quit(),
|
||||
.accept => |input| {
|
||||
defer allocator.free(input);
|
||||
var string = try allocator.alloc(u8, input.len);
|
||||
defer allocator.free(string);
|
||||
for (0.., input) |i, char| string[i] = @intCast(char);
|
||||
log.debug("Accepted input '{s}'", .{string});
|
||||
log.debug("Accepted input '{s}'", .{input});
|
||||
},
|
||||
.err => |err| log.err("Received {s} with message: {s}", .{ @errorName(err.err), err.msg }),
|
||||
else => {},
|
||||
@@ -165,5 +162,5 @@ const zterm = @import("zterm");
|
||||
const Color = zterm.Color;
|
||||
|
||||
const App = zterm.App(union(enum) {
|
||||
accept: []u21,
|
||||
accept: []u8,
|
||||
});
|
||||
|
||||
@@ -365,11 +365,31 @@ pub fn Scrollable(Event: type) type {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn Input(Event: type, Queue: type) fn (accept_event: meta.FieldEnum(Event)) type {
|
||||
pub fn Input(Event: type, Queue: type) fn (meta.FieldEnum(Event)) type {
|
||||
// NOTE the struct is necessary, as otherwise I cannot point to the function I want to return
|
||||
const input_struct = struct {
|
||||
pub fn input_fn(accept_event: meta.FieldEnum(Event)) type {
|
||||
// TODO create `comptime` check for `accept_event` that checks for the associated type of the field (of the `App.Event` union) which would need to be a `[]u8` or `[]u21`
|
||||
// -> for the corresponding type generate the corresponding conversion calls to trigger the correct event automatically!
|
||||
const event_type: enum { ascii, utf8 } = blk: { // check for type correctness and the associated type to use for the passed `accept_event`
|
||||
const t = @FieldType(Event, @tagName(accept_event));
|
||||
const err_msg = "Unexpected type for the associated input completion event to trigger. Only `[]u8` or `[]u21` are allowed.";
|
||||
switch (@typeInfo(t)) {
|
||||
.pointer => |pointer| {
|
||||
if (pointer.size != .slice) @compileError(err_msg);
|
||||
switch (@typeInfo(pointer.child)) {
|
||||
.int => |num| {
|
||||
if (num.signedness != .unsigned) @compileError(err_msg);
|
||||
switch (num.bits) {
|
||||
8 => break :blk .ascii,
|
||||
21 => break :blk .utf8,
|
||||
else => @compileError(err_msg),
|
||||
}
|
||||
},
|
||||
else => @compileError(err_msg),
|
||||
}
|
||||
},
|
||||
else => @compileError(err_msg),
|
||||
}
|
||||
};
|
||||
return struct {
|
||||
/// Offset from the end describing the current position of the cursor.
|
||||
cursor_offset: usize = 0,
|
||||
@@ -385,15 +405,10 @@ pub fn Input(Event: type, Queue: type) fn (accept_event: meta.FieldEnum(Event))
|
||||
color: Color,
|
||||
|
||||
pub fn init(color: Color) @This() {
|
||||
return .{
|
||||
.color = color,
|
||||
};
|
||||
return .{ .color = color };
|
||||
}
|
||||
};
|
||||
|
||||
// TODO make the event to trigger user defined (needs to be `comptime`)
|
||||
// - can this even be agnostic to `u8` / `u21`?
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator, queue: *Queue, configuration: Configuration) @This() {
|
||||
return .{
|
||||
.configuration = configuration,
|
||||
@@ -505,11 +520,24 @@ pub fn Input(Event: type, Queue: type) fn (accept_event: meta.FieldEnum(Event))
|
||||
// TODO enter to accept?
|
||||
// - shift+enter is not recognized by the input reader of `zterm`, so currently it is not possible to add newlines into the text box?
|
||||
if (key.eql(.{ .cp = input.Enter }) or key.eql(.{ .cp = input.KpEnter })) {
|
||||
this.queue.push(@unionInit(
|
||||
Event,
|
||||
@tagName(accept_event),
|
||||
try this.input.toOwnedSlice(),
|
||||
));
|
||||
switch (event_type) {
|
||||
.ascii => {
|
||||
// NOTE convert unicode characters to ascii characters; if non ascii characters are found this is will fail!
|
||||
var slice = try this.input.allocator.alloc(u8, this.input.items.len);
|
||||
for (0.., this.input.items) |i, c| slice[i] = @intCast(c);
|
||||
this.input.clearAndFree();
|
||||
this.queue.push(@unionInit(
|
||||
Event,
|
||||
@tagName(accept_event),
|
||||
slice,
|
||||
));
|
||||
},
|
||||
.utf8 => this.queue.push(@unionInit(
|
||||
Event,
|
||||
@tagName(accept_event),
|
||||
try this.input.toOwnedSlice(),
|
||||
)),
|
||||
}
|
||||
this.cursor_offset = 0;
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user