From f9e2954f4cd806719d7a844777c8b689db7e7795 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Sat, 25 Feb 2023 22:13:36 -0600 Subject: [PATCH] testing result with os.file open --- core/container/optional.onyx | 10 ++++++++++ core/container/result.onyx | 16 ++++++++++++++++ core/os/file.onyx | 17 +++++++---------- core/std.onyx | 1 + 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/core/container/optional.onyx b/core/container/optional.onyx index 33aafefb..86f54d10 100644 --- a/core/container/optional.onyx +++ b/core/container/optional.onyx @@ -83,6 +83,16 @@ Optional :: struct (Value_Type: type_expr) { return generate(); } + #doc """ + Returns the value inside the optional, if there is one. + If not, an assertion is thrown and the context's assert + handler must take care of it. + """ + unwrap :: (o: Optional) -> o.Value_Type { + if o.has_value do return o.value; + assert(false, "Unwrapping empty Optional."); + } + hash :: (o: Optional($T/core.hash.Hashable)) -> u32 { if !o.has_value do return 0; return core.hash.to_u32(o.value); diff --git a/core/container/result.onyx b/core/container/result.onyx index 2a14f62e..147e4bfe 100644 --- a/core/container/result.onyx +++ b/core/container/result.onyx @@ -54,6 +54,15 @@ Result_Data :: struct (T: type_expr, E: type_expr) { return r.__data.value; } + expect :: (r: #Self, msg: str) -> r.Ok_Type { + if r.status == .Err { + assert(false, msg); + return .{}; + } + + return r.__data.value; + } + transform :: (r: #Self, f: (r.Ok_Type) -> $R) => { if r.status == .Err do return r; return .{ .Ok, .{ value = f(r.__data.value) } }; @@ -76,6 +85,13 @@ Result_Data :: struct (T: type_expr, E: type_expr) { return #from_enclosing .{ .Err, .{ error = res.__data.error } }; } + or_return :: macro (r: Result($T, $E), v: $V) -> T { + res := r; + if res.status == .Ok do return res.__data.value; + + return #from_enclosing v; + } + format :: (o: ^conv.Format_Output, format: ^conv.Format, res: ^Result($T, $E)) { if res.status == .Ok { conv.format(o, "{}({\"})", res.status, res.__data.value); diff --git a/core/os/file.onyx b/core/os/file.onyx index 53e74215..c6764270 100644 --- a/core/os/file.onyx +++ b/core/os/file.onyx @@ -64,18 +64,18 @@ get_contents_from_file :: (file: ^File) -> str { return data[0 .. size]; } -open :: (path: str, mode := OpenMode.Read) -> (os.FileError, File) { +open :: (path: str, mode := OpenMode.Read) -> Result(File, os.FileError) { file := File.{ stream = .{ vtable = null }, data = .{}, }; file_data, error := fs.__file_open(path, mode); - if error != .None do return error, file; + if error != .None do return .{ .Err, .{error=error} }; file.data = file_data; file.vtable = ^fs.__file_stream_vtable; - return .None, file; + return .{ .Ok, .{value=file} }; } close :: (file: ^File) { @@ -87,8 +87,7 @@ get_contents :: #match { get_contents_from_file, (path: str) -> str { - error, file := open(path, .Read); - if error != .None do return .{ null, 0 }; + file := open(path, .Read)->or_return(null_str); defer close(^file); return get_contents(^file); @@ -103,8 +102,8 @@ with_file :: (path: str, mode := OpenMode.Read) -> Iterator(^File) { } c := new(Context); - if err, file_stream := open(path, mode); err == .None { - c.file_stream = file_stream; + if file_stream := open(path, mode); file_stream { + c.file_stream = file_stream->unwrap(); c.valid_file_stream = true; } @@ -156,9 +155,7 @@ file_logger_open :: (filename: str, allocator := context.allocator) -> ^File_Log file_logger.file = new(File, allocator); - error := os.FileError.None; - error, *file_logger.file = open(filename, mode=.Append); - assert(error == .None, "Unable to open file for logging."); + *file_logger.file = open(filename, mode=.Append)->expect("Unable to open file for logging."); return file_logger; } diff --git a/core/std.onyx b/core/std.onyx index fd0eb0c8..2df668c5 100644 --- a/core/std.onyx +++ b/core/std.onyx @@ -14,6 +14,7 @@ package core #load "./container/heap" #load "./container/pair" #load "./container/optional" +#load "./container/result" #load "./conv/conv" #load "./conv/format" -- 2.25.1