From 4cd974c11fb58490bceba91896338c0a0f1a8452 Mon Sep 17 00:00:00 2001 From: Charles Iliya Krempeaux Date: Sun, 14 Aug 2022 00:03:55 -0700 Subject: [PATCH] =?UTF-8?q?opt.Then()=20=E2=80=94=20I=20would=20prefer=20t?= =?UTF-8?q?hat=20map=20be=20a=20method,=20but=20the=20current=20implementa?= =?UTF-8?q?tion=20of=20Go=20generatics=20does=20not=20seem=20to=20support?= =?UTF-8?q?=20that?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- then.go | 44 ++++++++++++++++++++++++++ then_test.go | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 then.go create mode 100644 then_test.go diff --git a/then.go b/then.go new file mode 100644 index 0000000..2b39d0c --- /dev/null +++ b/then.go @@ -0,0 +1,44 @@ +package opt + +// Then applies the function ‘fn’ to the value inside of the optional-type ‘op’, if the optional-type ‘op’ is holding something, and returns the resulting optional-type. +// If the optional-type ‘op’ is holding nothing, then Then also returns nothing. +// +// For example: +// +// fn := func(s string) opt.Optional[byte] { +// +// if len(s) < 2 { +// return opt.Nothing[byte]() +// } +// +// return opt.Something[byte](s[1]) +// } +// +// var op opt.Optional[string] = opt.Something("Hello world!"") +// +// var result opt.Optional[byte] = opt.Then(op, fn) +// +// // result == opt.Something[byte]('e') +// +// // ... +// +// var op2 opt.Optional[string] = opt.Something[string]("X") +// +// var result2 opt.Optional[byte] = opt.Then(op, fn) +// +// // result2 == opt.Nothing[byte]() +// +// // ... +// +// var op2 opt.Optional[string] = opt.Nothing[string]() +// +// var result2 opt.Optional[byte] = opt.Then(op, fn) +// +// // result2 == opt.Nothing[byte]() +func Then[T1 any, T2 any](op Optional[T1], fn func(T1)Optional[T2]) Optional[T2] { + if !op.something { + return Nothing[T2]() + } + + return fn(op.value) +} diff --git a/then_test.go b/then_test.go new file mode 100644 index 0000000..92cbd8e --- /dev/null +++ b/then_test.go @@ -0,0 +1,88 @@ +package opt_test + +import ( + "github.com/reiver/go-opt" + + "testing" +) + +func TestThen_stringToUint(t *testing.T) { + + tests := []struct{ + Optional opt.Optional[string] + Expected opt.Optional[byte] + }{ + { + Optional: opt.Nothing[string](), + Expected: opt.Nothing[byte](), + }, + + + + { + Optional: opt.Something(""), + Expected: opt.Nothing[byte](), + }, + + + + { + Optional: opt.Something("A"), + Expected: opt.Nothing[byte](), + }, + { + Optional: opt.Something("B"), + Expected: opt.Nothing[byte](), + }, + { + Optional: opt.Something("C"), + Expected: opt.Nothing[byte](), + }, + + + + { + Optional: opt.Something("once"), + Expected: opt.Something[byte]('n'), + }, + { + Optional: opt.Something("twice"), + Expected: opt.Something[byte]('w'), + }, + { + Optional: opt.Something("thrice"), + Expected: opt.Something[byte]('h'), + }, + { + Optional: opt.Something("fource"), + Expected: opt.Something[byte]('o'), + }, + } + + for testNumber, test := range tests { + + fn := func(s string) opt.Optional[byte] { + if len(s) < 2 { + return opt.Nothing[byte]() + } + + return opt.Something[byte](s[1]) + } + + thened := opt.Then(test.Optional, fn) + + { + expected := test.Expected + actual := thened + + if expected != actual { + t.Errorf("For test #%d, the actual value is not what was expected.", testNumber) + t.Logf("EXPECTED: (%T) %#v", expected, expected) + t.Logf("ACTUAL: (%T) %#v", actual, actual) + t.Logf("OPTIONAL: (%T), %#v", test.Optional, test.Optional) + /////////////////////// CONTINUE + continue + } + } + } +}