From 8033203ef6d331b62acadad369dc7c8aa8acfea5 Mon Sep 17 00:00:00 2001 From: spaceface Date: Mon, 22 Feb 2021 17:44:15 +0100 Subject: [PATCH] builtin: add an Option2 struct (#8890) --- examples/eventbus/eventbus.v | 2 +- .../modules/some_module/some_module.v | 8 +-- vlib/builtin/option.v | 72 ++++++++++++++++--- vlib/v/checker/checker.v | 3 +- vlib/v/gen/c/cgen.v | 2 +- 5 files changed, 70 insertions(+), 17 deletions(-) diff --git a/examples/eventbus/eventbus.v b/examples/eventbus/eventbus.v index 82268abe8a..d970b5525a 100644 --- a/examples/eventbus/eventbus.v +++ b/examples/eventbus/eventbus.v @@ -8,6 +8,6 @@ fn main(){ some_module.do_work() } -fn on_error(sender voidptr, e &some_module.Error, x voidptr) { +fn on_error(sender voidptr, e &some_module.MyError, x voidptr) { println(e.message) } diff --git a/examples/eventbus/modules/some_module/some_module.v b/examples/eventbus/modules/some_module/some_module.v index a3b7bfed55..093cccc7a8 100644 --- a/examples/eventbus/modules/some_module/some_module.v +++ b/examples/eventbus/modules/some_module/some_module.v @@ -7,12 +7,12 @@ const ( ) pub struct Work { - pub: +pub: hours int } -pub struct Error { - pub: +pub struct MyError { +pub: message string } @@ -21,7 +21,7 @@ pub fn do_work(){ for i in 0..20 { println("working...") if i == 15 { - error := &Error{"There was an error."} + error := &MyError{"There was an error."} eb.publish("error", work, error) eb.publish("error", work, error) return diff --git a/vlib/builtin/option.v b/vlib/builtin/option.v index 2591426eb6..5dec5497ab 100644 --- a/vlib/builtin/option.v +++ b/vlib/builtin/option.v @@ -3,16 +3,6 @@ // that can be found in the LICENSE file. module builtin -/* -struct Option2 { - ok bool - is_none bool - error string - ecode int - data T -} -*/ -// OptionBase is the the base of V's internal optional return system. struct OptionBase { ok bool is_none bool @@ -81,3 +71,65 @@ pub fn error_with_code(message string, code int) Option { ecode: code } } + +struct Option2 { + state byte + err Error +} + +// OptionBase is the the base of V's internal optional return system. +struct OptionBase2 { + state byte + err Error + // Data is trailing after err + // and is not included in here but in the + // derived Option2_xxx types +} + +// Error holds information about an error instance +struct Error { + msg string + code int +} + +// /* +pub fn (o Option2) str() string { + if o.state == 0 { + return 'Option2{ ok }' + } + if o.state == 1 { + return 'Option2{ none }' + } + return 'Option2{ err: "$o.err.msg" }' +} + +// opt_none is used internally when returning `none`. +fn opt_none2() Option2 { + return Option2{ + state: 1 + } +} + +// error returns an optional containing the error given in `message`. +// `if ouch { return error('an error occurred') }` +pub fn error2(message string) Option2 { + return Option2{ + state: 2 + err: { + msg: message + } + } +} + +// error_with_code returns an optional containing both error `message` and error `code`. +// `if ouch { return error_with_code('an error occurred',1) }` +pub fn error_with_code2(message string, code int) Option2 { + return Option2{ + state: 2 + err: { + msg: message + code: code + } + } +} +// */ diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 6abf09dc0f..3a003eb7f1 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2355,7 +2355,8 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) { } return_stmt.types = got_types // allow `none` & `error (Option)` return types for function that returns optional - if exp_is_optional && got_types[0].idx() in [table.none_type_idx, c.table.type_idxs['Option']] { + if exp_is_optional + && got_types[0].idx() in [table.none_type_idx, c.table.type_idxs['Option'], c.table.type_idxs['Option2']] { return } if expected_types.len > 0 && expected_types.len != got_types.len { diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 589e1196db..9289bee7b3 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -5286,7 +5286,7 @@ fn (mut g Gen) write_init_function() { } const ( - builtins = ['string', 'array', 'KeyValue', 'DenseArray', 'map', 'Option'] + builtins = ['string', 'array', 'KeyValue', 'DenseArray', 'map', 'Option', 'Error', 'Option2'] ) fn (mut g Gen) write_builtin_types() {