*o = .{ Some = value };
}
+ #doc "Flattens nested optionals."
+ // @Bug should be able to say ? ? $T here.
+ flatten :: (o1: ? Optional($T)) -> ? T {
+ switch o1 {
+ case o2: .Some {
+ return o2;
+ }
+
+ case .None ---
+ }
+
+ return .None;
+ }
+
#doc "Monadic chaining operation."
and_then :: (o: ?$T, transform: (T) -> ?$R) -> ?R {
return switch o {
case #default {
if info.kind == .Enum {
- // TEMPORARY this needs to look at the backing type for the
- // enum in order to know how large this integer should be.
- *cast(&u32) target = ~~ str_to_i64(to_parse);
+ val := str_to_i64(to_parse);
+
+ einfo := info->as_enum();
+ switch einfo.backing_type {
+ case i8, u8 do *cast(&u8) target = ~~val;
+ case i16, u16 do *cast(&u16) target = ~~val;
+ case i32, u32 do *cast(&u32) target = ~~val;
+ case i64, u64 do *cast(&u64) target = ~~val;
+ }
+
return true;
}
if info.kind == .Union && union_constructed_from(data_type, Optional) {
parsed_successful := parse_any(memory.ptr_add(target, info.alignment), info->as_union().variants[1].type, to_parse, string_allocator);
if !parsed_successful {
- *cast(& u32) target = ~~ Optional(void).tag_enum.None;
+ *cast(& u8) target = ~~ Optional(void).tag_enum.None;
} else {
- *cast(& u32) target = ~~ Optional(void).tag_enum.Some;
+ *cast(& u8) target = ~~ Optional(void).tag_enum.Some;
}
+
+ return true;
}
}
}
return false;
}
+
+
+#doc """
+ Shortcut to parse a type `T` using `parse_any`.
+"""
+parse :: ($T: type_expr, to_parse: str) -> ? T {
+ v: T;
+ if #this_package.parse_any(&v, to_parse) {
+ return v;
+ } else {
+ return .None;
+ }
+}
+
+#doc """
+ Shortcut to parse a type `T` using `parse_any`, and specify an allocator.
+"""
+parse_with_allocator :: ($T: type_expr, to_parse: str, allocator: Allocator) -> ? T {
+ v: T;
+ if #this_package.parse_any(&v, to_parse, allocator) {
+ return v;
+ } else {
+ return .None;
+ }
+}
+
--- /dev/null
+use core {*}
+
+main :: () {
+ conv.parse(i32, "1203") |> println();
+ conv.parse(f32, "45.32") |> println();
+ conv.parse(? i8, "72") |> Optional.flatten() |> println();
+
+ conv.parse(Food, "2") |> println();
+
+ "12 34 56 78 90"
+ |> string.split_iter(" ")
+ |> iter.map(x => conv.parse(i32, x))
+ |> iter.collect()
+ |> println();
+}
+
+Food :: enum {
+ Apple;
+ Banana;
+ Coconut;
+}