What is the best way to throw or return from an assignment switch? I want to do something like:
func pick(request : MyRequest) : Result<MyVariant, Text>{
let config = switch(request.config){
case(#variant1(data)){#internal;};
case(#variant2(pullRequest)){#internal2}; };
case(#badVariant){return #err("Never should be here"}; // won't compile due to a type error
// or case(#badVariant){throw #err("Never should be here"}; but returns an Error type and doesnt work
};
return #ok(config);
}
I would skip the assignment and instead return #ok(…)
inside of the case:
func pick(request : MyRequest) : Result<MyVariant, Text> {
switch(request.config) {
case(#variant1(data)) { #ok(#internal); };
case(#variant2(pullRequest)) { #ok(#internal2); };
case(#badVariant) { #err("Never should be here"; };
};
};
That is a good strategy if I’m ready to return…and my example was perhaps a bit simplistic. In the real world I’m setting up this variant to go into a function call further down in the function, so I can’t return right away in every scenario.
In that case I would keep what I did but create a let
binding for the result and then use map
.
In languages with special syntax like do
notation or Rust’s ?
you can use that instead.
If you don’t need the Result type immediately, then you can use do?
.
func pick(request : MyRequest) : Result<MyVariant, Text>{
let result = do? {
let config = switch (request.config) {
case (#variant1(data)) { #internal };
case (#variant2(pullRequest)) { #internal2 };
case (#badVariant) { null! };
};
// ...do something with config
// ...produce result
};
return Result.fromOption(result, "error message");
}
At some point, we’d like to generalise do?
to enable producing something like Result directly, but that’s not there yet.
1 Like
.fromOption! Perfect. I need to re read the Base Libraries now that I actually know motoko.