the wheels look like they're spinning because they are
Had to refactor the multi-value parameter stuff to push some of the key information in to the generics structure, as they necessarily change the conversion function signature. Some code has gotten folded together by being a bit sloppier with inputs and outputs. This should put us well on our way to having functioning value conversion, which I think is the main major feature remaining besides help text generation. Hopefully I won't need to rewrite everything like this again. While this design seems to be on track to incorporate all of the main features I am interested in, it has been a lot of work to wrangle it around, and there is still a lot of work left before I can put a bow on it.
This commit is contained in:
parent
0fbbf34156
commit
2c0842f5d4
@ -8,11 +8,18 @@ pub const ConversionError = error{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub fn ConverterSignature(comptime gen: ParameterGenerics) type {
|
pub fn ConverterSignature(comptime gen: ParameterGenerics) type {
|
||||||
return *const fn (gen.ContextType, []const u8) ConversionError!gen.ResultType();
|
return *const fn (gen.UserContext, gen.IntermediateType()) ConversionError!gen.ConvertedType();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn FlagConverterSignature(comptime UserContext: type, comptime multi: bool) type {
|
||||||
|
comptime if (multi)
|
||||||
|
return *const fn (UserContext, std.ArrayList([]const u8)) ConversionError!std.ArrayList(bool)
|
||||||
|
else
|
||||||
|
return *const fn (UserContext, []const u8) ConversionError!bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn default_converter(comptime gen: ParameterGenerics) ?ConverterSignature(gen) {
|
pub fn default_converter(comptime gen: ParameterGenerics) ?ConverterSignature(gen) {
|
||||||
return switch (@typeInfo(gen.ResultType())) {
|
return switch (@typeInfo(gen.OutputType)) {
|
||||||
.Bool => flag_converter(gen),
|
.Bool => flag_converter(gen),
|
||||||
.Int => int_converter(gen),
|
.Int => int_converter(gen),
|
||||||
.Pointer => |info| if (info.size == .Slice and info.child == u8)
|
.Pointer => |info| if (info.size == .Slice and info.child == u8)
|
||||||
@ -24,9 +31,23 @@ pub fn default_converter(comptime gen: ParameterGenerics) ?ConverterSignature(ge
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fn multi_converter(comptime gen: ParameterGenerics) ?ConverterSignature(gen) {
|
||||||
|
// const converter = default_converter(gen) orelse @compileError("no default converter");
|
||||||
|
|
||||||
|
// return struct {
|
||||||
|
// pub fn handler(_: UserContext, input: std.ArrayList([]const u8)) ConversionError!std.ArrayList(OutputType) {
|
||||||
|
// var output = std.ArrayList(OutputType).initCapacity(input.allocator, input.items.len) catch return ConversionError.BadValue;
|
||||||
|
|
||||||
|
// for (input.items) |item| {
|
||||||
|
// output.appendAssumeCapacity()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }.handler;
|
||||||
|
// }
|
||||||
|
|
||||||
fn flag_converter(comptime gen: ParameterGenerics) ConverterSignature(gen) {
|
fn flag_converter(comptime gen: ParameterGenerics) ConverterSignature(gen) {
|
||||||
return struct {
|
return struct {
|
||||||
pub fn handler(_: gen.ContextType, input: []const u8) ConversionError!bool {
|
pub fn handler(_: gen.UserContext, input: []const u8) ConversionError!bool {
|
||||||
// treat an empty string as falsy
|
// treat an empty string as falsy
|
||||||
if (input.len == 0) return false;
|
if (input.len == 0) return false;
|
||||||
|
|
||||||
@ -46,29 +67,29 @@ fn flag_converter(comptime gen: ParameterGenerics) ConverterSignature(gen) {
|
|||||||
|
|
||||||
fn string_converter(comptime gen: ParameterGenerics) ConverterSignature(gen) {
|
fn string_converter(comptime gen: ParameterGenerics) ConverterSignature(gen) {
|
||||||
return struct {
|
return struct {
|
||||||
pub fn handler(_: gen.ContextType, value: []const u8) ConversionError![]const u8 {
|
pub fn handler(_: gen.UserContext, value: []const u8) ConversionError![]const u8 {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
}.handler;
|
}.handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn int_converter(comptime gen: ParameterGenerics) ConverterSignature(gen) {
|
fn int_converter(comptime gen: ParameterGenerics) ConverterSignature(gen) {
|
||||||
const IntType = gen.ResultType();
|
const IntType = gen.OutputType;
|
||||||
comptime std.debug.assert(@typeInfo(IntType) == .Int);
|
comptime std.debug.assert(@typeInfo(IntType) == .Int);
|
||||||
|
|
||||||
return struct {
|
return struct {
|
||||||
pub fn handler(_: gen.ContextType, value: []const u8) ConversionError!IntType {
|
pub fn handler(_: gen.UserContext, value: []const u8) ConversionError!IntType {
|
||||||
return std.fmt.parseInt(IntType, value, 0) catch return ConversionError.BadValue;
|
return std.fmt.parseInt(IntType, value, 0) catch return ConversionError.BadValue;
|
||||||
}
|
}
|
||||||
}.handler;
|
}.handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn choice_converter(comptime gen: ParameterGenerics) ConverterSignature(gen) {
|
fn choice_converter(comptime gen: ParameterGenerics) ConverterSignature(gen) {
|
||||||
const EnumType = gen.ResultType();
|
const EnumType = gen.OutputType;
|
||||||
|
|
||||||
return struct {
|
return struct {
|
||||||
pub fn handler(_: gen.ContextType, value: []const u8) ConversionError!EnumType {
|
pub fn handler(_: gen.UserContext, value: []const u8) ConversionError!EnumType {
|
||||||
return std.meta.stringToEnum(gen.ResultType(), value) orelse ConversionError.BadValue;
|
return std.meta.stringToEnum(gen.ConvertedType(), value) orelse ConversionError.BadValue;
|
||||||
}
|
}
|
||||||
}.handler;
|
}.handler;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -79,6 +79,12 @@ pub fn SliceIterator(comptime T: type) type {
|
|||||||
return self.data[self.index];
|
return self.data[self.index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn rewind(self: *@This()) void {
|
||||||
|
if (self.index == 0) return;
|
||||||
|
|
||||||
|
self.index -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn skip(self: *@This()) void {
|
pub fn skip(self: *@This()) void {
|
||||||
if (self.index == self.data.len) return;
|
if (self.index == self.data.len) return;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user