ziglings/exercises/024_errors4.zig

70 lines
1.9 KiB
Zig
Raw Normal View History

2021-01-30 20:00:32 -05:00
//
// Using `catch` to replace an error with a default value is a bit
// of a blunt instrument since it doesn't matter what the error is.
//
// Catch lets us capture the error value and perform additional
// actions with this form:
//
// canFail() catch |err| {
// if (err == FishError.TunaMalfunction) {
// ...
// }
// };
//
const std = @import("std");
const MyNumberError = error{
TooSmall,
TooBig,
};
pub fn main() void {
// The "catch 0" below is just our way of dealing with the fact
// that makeJustRight() returns a error union (for now).
var a: u32 = makeJustRight(44) catch 0;
var b: u32 = makeJustRight(14) catch 0;
2021-02-15 16:55:44 -05:00
var c: u32 = makeJustRight(4) catch 0;
2021-01-30 20:00:32 -05:00
2021-02-15 16:55:44 -05:00
std.debug.print("a={}, b={}, c={}", .{ a, b, c });
2021-01-30 20:00:32 -05:00
}
// In this silly example we've split the responsibility of making
// a number just right into four (!) functions:
//
// makeJustRight() Calls fixTooBig(), cannot fix any errors.
// fixTooBig() Calls fixTooSmall(), fixes TooBig errors.
// fixTooSmall() Calls detectProblems(), fixes TooSmall errors.
// detectProblems() Returns the number or an error.
//
fn makeJustRight(n: u32) MyNumberError!u32 {
2021-02-15 16:55:44 -05:00
return fixTooBig(n) catch |err| {
return err;
};
2021-01-30 20:00:32 -05:00
}
fn fixTooBig(n: u32) MyNumberError!u32 {
return fixTooSmall(n) catch |err| {
if (err == MyNumberError.TooBig) {
return 20;
}
2021-02-15 16:55:44 -05:00
2021-01-30 20:00:32 -05:00
return err;
};
}
fn fixTooSmall(n: u32) MyNumberError!u32 {
// Oh dear, this is missing a lot! But don't worry, it's nearly
2021-02-15 16:55:44 -05:00
// identical to fixTooBig() above.
2021-01-30 20:00:32 -05:00
//
// If we get a TooSmall error, we should return 10.
// If we get any other error, we should return that error.
// Otherwise, we return the u32 number.
2021-03-14 01:26:52 -05:00
return detectProblems(n) ???
2021-01-30 20:00:32 -05:00
}
fn detectProblems(n: u32) MyNumberError!u32 {
if (n < 10) return MyNumberError.TooSmall;
if (n > 20) return MyNumberError.TooBig;
return n;
}