From c6a829ce8287ab85e70f3ea45dc885acd3c18082 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Fri, 24 Apr 2020 18:35:33 +0300 Subject: [PATCH] cgen: support for error('abc').str() and printing errors --- vlib/builtin/option.v | 11 ++++++++++- vlib/v/gen/cgen.v | 11 +++++++++++ vlib/v/tests/option_print_errors_test.v | 21 +++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 vlib/v/tests/option_print_errors_test.v diff --git a/vlib/builtin/option.v b/vlib/builtin/option.v index 133c8d9e23..a0c64d87e7 100644 --- a/vlib/builtin/option.v +++ b/vlib/builtin/option.v @@ -21,6 +21,16 @@ struct Option { is_none bool } +pub fn (o Option) str() string { + if o.ok && !o.is_none { + return 'Option{ data: ' + o.data[0..32].hex() + ' }' + } + if o.is_none { + return 'Option{ none }' + } + return 'Option{ error: "${o.error}" }' +} + // `fn foo() ?Foo { return foo }` => `fn foo() ?Foo { return opt_ok(foo); }` fn opt_ok(data voidptr, size int) Option { if size >= 400 { @@ -52,4 +62,3 @@ pub fn error_with_code(s string, code int) Option { ecode: code } } - diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index a323f8bf1c..e21169a080 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -2315,6 +2315,8 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { g.write('%"PRId64"') } else if node.expr_types[i] == table.u64_type { g.write('%"PRIu64"') + } else if g.typ( node.expr_types[i] ).starts_with('Option') { + g.write('%.*s') } else { g.write('%"PRId32"') } @@ -2405,6 +2407,15 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { g.write('${str_fn_name}(') g.expr(expr) g.write(',0).str') + } else if g.typ( node.expr_types[i] ).starts_with('Option') { + str_fn_name := 'Option_str' + g.write('${str_fn_name}((Option)') + g.expr(expr) + g.write(')') + g.write('.len, ') + g.write('${str_fn_name}((Option)') + g.expr(expr) + g.write(').str') } else { g.expr(expr) } diff --git a/vlib/v/tests/option_print_errors_test.v b/vlib/v/tests/option_print_errors_test.v new file mode 100644 index 0000000000..3992c0a75a --- /dev/null +++ b/vlib/v/tests/option_print_errors_test.v @@ -0,0 +1,21 @@ + +fn test_error_can_be_converted_to_string(){ + assert 'Option{ error: "an error" }' == error('an error').str() +} + +fn test_error_can_be_assigned_to_a_variable(){ + f := error('an error') + assert 'Option{ error: "an error" }' == f.str() +} + +fn test_error_can_be_printed(){ + f := error('an error') + println(f) + assert true +} + +fn test_error_can_be_interpolated_in_a_string(){ + f := error('an error') + s := 'hi $f' + assert s == 'hi Option{ error: "an error" }' +}