From a1cacd6e19d06692e067ba171c04a26de0cf8ad8 Mon Sep 17 00:00:00 2001 From: Camila Date: Thu, 23 Feb 2023 07:18:46 -0500 Subject: [PATCH] add Result to blockchain types (#3894) Added the Result type to the same page where Identity, ContractId, and Address are covered. Definition was taken from standard library repo - https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/result.sw --------- Co-authored-by: Camila Ramos Co-authored-by: Mohammad Fawaz --- docs/book/src/SUMMARY.md | 1 + .../src/basics/commonly_used_library_types.md | 38 +++++++++++++++++++ examples/Forc.lock | 10 +++++ examples/Forc.toml | 2 + examples/option/Forc.toml | 8 ++++ examples/option/src/main.sw | 20 ++++++++++ examples/result/Forc.toml | 8 ++++ examples/result/src/main.sw | 21 ++++++++++ sway-lib-std/src/option.sw | 4 +- sway-lib-std/src/result.sw | 3 ++ sway-lsp/tests/lib.rs | 22 +++++------ 11 files changed, 125 insertions(+), 12 deletions(-) create mode 100644 docs/book/src/basics/commonly_used_library_types.md create mode 100644 examples/option/Forc.toml create mode 100644 examples/option/src/main.sw create mode 100644 examples/result/Forc.toml create mode 100644 examples/result/src/main.sw diff --git a/docs/book/src/SUMMARY.md b/docs/book/src/SUMMARY.md index 5cd5284fb8e..c633d09c488 100644 --- a/docs/book/src/SUMMARY.md +++ b/docs/book/src/SUMMARY.md @@ -21,6 +21,7 @@ - [Sway Language Basics](./basics/index.md) - [Variables](./basics/variables.md) - [Built-in Types](./basics/built_in_types.md) + - [Commonly Used Library Types](./basics/commonly_used_library_types.md) - [Blockchain Types](./basics/blockchain_types.md) - [Functions](./basics/functions.md) - [Structs, Tuples, and Enums](./basics/structs_tuples_and_enums.md) diff --git a/docs/book/src/basics/commonly_used_library_types.md b/docs/book/src/basics/commonly_used_library_types.md new file mode 100644 index 00000000000..f84405543f7 --- /dev/null +++ b/docs/book/src/basics/commonly_used_library_types.md @@ -0,0 +1,38 @@ +# Commonly Used Library Types + +The Sway Standard Library is the foundation of portable Sway software, a set of minimal shared abstractions for the broader Sway ecosystem. It offers core types, library-defined operations on language primitives, native asset management, blockchain contextual operations, access control, storage management, and support for types from other VMs, among many other things. Reference the standard library docs [here](https://fuellabs.github.io/sway/master/std/index.html). + +## `Result` + +Type `Result` is the type used for returning and propagating errors. It is an `enum` with two variants: `Ok(T)`, representing success and containing a value, and `Err(E)`, representing error and containing an error value. The `T` and `E` in this definition are type parameters, allowing `Result` to be generic and to be used with any types. + +```sway +{{#include ../../../../sway-lib-std/src/result.sw:docs_result}} +``` + +Functions return `Result` whenever errors are expected and recoverable. Take the following example: + +```sway +{{#include ../../../../examples/result/src/main.sw}} +``` + +## `Option` + +Type `Option` represents an optional value: every `Option` is either `Some` and contains a value, or `None`, and does not. `Option` types are very common in Sway code, as they have a number of uses: + +- Initial values where `None` can be used as an initializer. +- Return value for otherwise reporting simple errors, where `None` is returned on error. + +The implementation of `Option` matches on the variant: if it's `Ok` it returns the inner value, if it's `None`, it [reverts](https://github.com/FuelLabs/fuel-specs/blob/master/src/vm/instruction_set.md#rvrt-revert). + +```sway +{{#include ../../../../sway-lib-std/src/option.sw:docs_option}} +``` + +`Option` is commonly paired with pattern matching to query the presence of a value and take action, allowing developers to choose how to handle the `None` case. + +Below is an example that uses pattern matching to handle invalid divisions by 0 by returning an `Option`: + +```sway +{{#include ../../../../examples/option/src/main.sw}} +``` diff --git a/examples/Forc.lock b/examples/Forc.lock index 184e3378652..6be9d993eeb 100644 --- a/examples/Forc.lock +++ b/examples/Forc.lock @@ -79,11 +79,21 @@ name = 'native_token' source = 'member' dependencies = ['std'] +[[package]] +name = 'option' +source = 'member' +dependencies = ['std'] + [[package]] name = 'ownership' source = 'member' dependencies = ['std'] +[[package]] +name = 'result' +source = 'member' +dependencies = ['std'] + [[package]] name = 'signatures' source = 'member' diff --git a/examples/Forc.toml b/examples/Forc.toml index e3a072ad92a..0b4e775336c 100644 --- a/examples/Forc.toml +++ b/examples/Forc.toml @@ -17,8 +17,10 @@ members = [ "match_statements", "msg_sender", "native_token", + "option", "ownership", "ref_mut_params", + "result", "signatures", "storage_example", "storage_map", diff --git a/examples/option/Forc.toml b/examples/option/Forc.toml new file mode 100644 index 00000000000..293c23f4068 --- /dev/null +++ b/examples/option/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "option" + +[dependencies] +std = { path = "../../sway-lib-std" } diff --git a/examples/option/src/main.sw b/examples/option/src/main.sw new file mode 100644 index 00000000000..050fb40d530 --- /dev/null +++ b/examples/option/src/main.sw @@ -0,0 +1,20 @@ +script; + +fn divide(numerator: u64, denominator: u64) -> Option { + if denominator == 0 { + Option::None + } else { + Option::Some(numerator / denominator) + } +} + +fn main() { + let result = divide(6, 2); + // Pattern match to retrieve the value + match result { + // The division was valid + Option::Some(x) => std::logging::log(x), + // The division was invalid + Option::None => std::logging::log("Cannot divide by 0"), + } +} diff --git a/examples/result/Forc.toml b/examples/result/Forc.toml new file mode 100644 index 00000000000..f3aef8f1410 --- /dev/null +++ b/examples/result/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "result" + +[dependencies] +std = { path = "../../sway-lib-std" } diff --git a/examples/result/src/main.sw b/examples/result/src/main.sw new file mode 100644 index 00000000000..4c752031131 --- /dev/null +++ b/examples/result/src/main.sw @@ -0,0 +1,21 @@ +script; + +enum MyContractError { + DivisionByZero: (), +} + +fn divide(numerator: u64, denominator: u64) -> Result { + if (denominator == 0) { + return Result::Err(MyContractError::DivisionByZero); + } else { + Result::Ok(numerator / denominator) + } +} + +fn main() -> Result { + let result = divide(20, 2); + match result { + Result::Ok(value) => Result::Ok(value), + Result::Err(MyContractError::DivisionByZero) => Result::Err("Fail"), + } +} diff --git a/sway-lib-std/src/option.sw b/sway-lib-std/src/option.sw index 09912b09276..29dcda8e4cc 100644 --- a/sway-lib-std/src/option.sw +++ b/sway-lib-std/src/option.sw @@ -77,13 +77,15 @@ library option; use ::result::Result; use ::revert::revert; -/// The `Option` type. See the module level documentation for more. +// ANCHOR: docs_option +/// `Option` is a type that represents an optional value. pub enum Option { /// No value. None: (), /// Some value of type `T`. Some: T, } +// ANCHOR_END: docs_option // Type implementation // diff --git a/sway-lib-std/src/result.sw b/sway-lib-std/src/result.sw index c4f9381be55..aaa4818960a 100644 --- a/sway-lib-std/src/result.sw +++ b/sway-lib-std/src/result.sw @@ -57,6 +57,7 @@ library result; use ::revert::revert; +// ANCHOR: docs_result /// `Result` is a type that represents either success (`Ok`) or failure (`Err`). pub enum Result { /// Contains the success value. @@ -64,6 +65,8 @@ pub enum Result { /// Contains the error value. Err: E, } +// ANCHOR_END: docs_result + // Type implementation // diff --git a/sway-lsp/tests/lib.rs b/sway-lsp/tests/lib.rs index 2b40434b0cd..dd5c2d6215e 100644 --- a/sway-lsp/tests/lib.rs +++ b/sway-lsp/tests/lib.rs @@ -244,7 +244,7 @@ async fn go_to_definition_for_fields() { req_uri: &uri, req_line: 5, req_char: 8, - def_line: 80, + def_line: 81, def_start_char: 9, def_end_char: 15, def_path: "sway-lib-std/src/option.sw", @@ -300,7 +300,7 @@ async fn go_to_definition_inside_turbofish() { req_uri: &uri, req_line: 15, req_char: 12, - def_line: 80, + def_line: 81, def_start_char: 9, def_end_char: 15, def_path: "sway-lib-std/src/option.sw", @@ -320,7 +320,7 @@ async fn go_to_definition_inside_turbofish() { req_uri: &uri, req_line: 20, req_char: 19, - def_line: 60, + def_line: 61, def_start_char: 9, def_end_char: 15, def_path: "sway-lib-std/src/result.sw", @@ -378,7 +378,7 @@ async fn go_to_definition_for_matches() { req_uri: &uri, req_line: 25, req_char: 19, - def_line: 80, + def_line: 81, def_start_char: 9, def_end_char: 15, def_path: "sway-lib-std/src/option.sw", @@ -396,7 +396,7 @@ async fn go_to_definition_for_matches() { req_uri: &uri, req_line: 25, req_char: 27, - def_line: 84, + def_line: 85, def_start_char: 4, def_end_char: 8, def_path: "sway-lib-std/src/option.sw", @@ -411,7 +411,7 @@ async fn go_to_definition_for_matches() { req_uri: &uri, req_line: 26, req_char: 17, - def_line: 82, + def_line: 83, def_start_char: 4, def_end_char: 8, def_path: "sway-lib-std/src/option.sw", @@ -526,7 +526,7 @@ async fn go_to_definition_for_paths() { req_uri: &uri, req_line: 10, req_char: 27, - def_line: 80, + def_line: 81, def_start_char: 9, def_end_char: 15, def_path: "sway-lib-std/src/option.sw", @@ -962,14 +962,14 @@ async fn go_to_definition_for_variables() { definition_check_with_req_offset(&mut service, &mut go_to, 53, 21, &mut i).await; // Complex type ascriptions - go_to.def_line = 60; + go_to.def_line = 61; go_to.def_start_char = 9; go_to.def_end_char = 15; go_to.def_path = "sway-lib-std/src/result.sw"; definition_check_with_req_offset(&mut service, &mut go_to, 56, 22, &mut i).await; definition_check_with_req_offset(&mut service, &mut go_to, 11, 31, &mut i).await; definition_check_with_req_offset(&mut service, &mut go_to, 11, 60, &mut i).await; - go_to.def_line = 80; + go_to.def_line = 81; go_to.def_path = "sway-lib-std/src/option.sw"; definition_check_with_req_offset(&mut service, &mut go_to, 56, 28, &mut i).await; definition_check_with_req_offset(&mut service, &mut go_to, 11, 39, &mut i).await; @@ -1054,7 +1054,7 @@ async fn go_to_definition_for_consts() { definition_check_with_req_offset(&mut service, &mut go_to, 10, 17, &mut i).await; // Complex type ascriptions - go_to.def_line = 80; + go_to.def_line = 81; go_to.def_start_char = 9; go_to.def_end_char = 15; go_to.def_path = "sway-lib-std/src/option.sw"; @@ -1147,7 +1147,7 @@ async fn go_to_definition_for_structs() { req_uri: &uri, req_line: 16, req_char: 11, - def_line: 80, + def_line: 81, def_start_char: 9, def_end_char: 15, def_path: "sway-lib-std/src/option.sw",