opt.Map() — I would prefer that map be a method, but the current implementation of Go generatics does not seem to support that
							parent
							
								
									d7e8552eea
								
							
						
					
					
						commit
						bfb598fbd1
					
				|  | @ -0,0 +1,47 @@ | |||
| package opt | ||||
| 
 | ||||
| // Map applies the function ‘fn’ to the value inside of the optional-type ‘op’, if the optional-type ‘op’ is holding something, and returns it as a new optional-type.
 | ||||
| // If the optional-type ‘op’ is holding nothing, then Map also returns nothing.
 | ||||
| //
 | ||||
| // For example:
 | ||||
| //
 | ||||
| //	var op opt.Optional[string] = opt.Something("Hello world!")
 | ||||
| //	
 | ||||
| //	var result opt.Optional[string] = opt.Map(op, strings.ToUpper)
 | ||||
| //	
 | ||||
| //	// result == opt.Something[string]("HELLO WORLD!")
 | ||||
| //	
 | ||||
| //	// ...
 | ||||
| //	
 | ||||
| //	var op2 opt.Optional[string] = opt.Nothing[string]()
 | ||||
| //	
 | ||||
| //	var result2 opt.Optional[string] = opt.Map(op, strings.ToUpper)
 | ||||
| //	
 | ||||
| //	// result2 == opt.Nothing[string]()
 | ||||
| //
 | ||||
| // Or also, for example:
 | ||||
| //
 | ||||
| //	fn := func(s string) int {
 | ||||
| //		return len(s)
 | ||||
| //	}
 | ||||
| //	
 | ||||
| //	var op opt.Optional[string] = opt.Something("Hello world!")
 | ||||
| //	
 | ||||
| //	var result opt.Optional[int] = opt.Map(op, fn)
 | ||||
| //	
 | ||||
| //	// result == opt.Something[int](12)
 | ||||
| //	
 | ||||
| //	// ...
 | ||||
| //	
 | ||||
| //	var op2 opt.Optional[string] = opt.Nothing[string]()
 | ||||
| //	
 | ||||
| //	var result2 opt.Optional[int] = opt.Map(op, fn)
 | ||||
| //	
 | ||||
| //	// result2 == opt.Nothing[int]()
 | ||||
| func Map[T1 any, T2 any](op Optional[T1], fn func(T1)T2) Optional[T2] { | ||||
| 	if !op.something { | ||||
| 		return Nothing[T2]() | ||||
| 	} | ||||
| 
 | ||||
| 	return Something(fn(op.value)) | ||||
| } | ||||
|  | @ -0,0 +1,69 @@ | |||
| package opt_test | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/reiver/go-opt" | ||||
| 
 | ||||
| 	"testing" | ||||
| ) | ||||
| 
 | ||||
| func TestMap_stringToUint(t *testing.T) { | ||||
| 
 | ||||
| 	tests := []struct{ | ||||
| 		Optional opt.Optional[string] | ||||
| 		Expected opt.Optional[int] | ||||
| 	}{ | ||||
| 		{ | ||||
| 			Optional: opt.Nothing[string](), | ||||
| 			Expected: opt.Nothing[int](), | ||||
| 		}, | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		{ | ||||
| 			Optional: opt.Something(""), | ||||
| 			Expected: opt.Something[int](0), | ||||
| 		}, | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		{ | ||||
| 			Optional: opt.Something("once"), | ||||
| 			Expected: opt.Something[int](4), | ||||
| 		}, | ||||
| 		{ | ||||
| 			Optional: opt.Something("twice"), | ||||
| 			Expected: opt.Something[int](5), | ||||
| 		}, | ||||
| 		{ | ||||
| 			Optional: opt.Something("thrice"), | ||||
| 			Expected: opt.Something[int](6), | ||||
| 		}, | ||||
| 		{ | ||||
| 			Optional: opt.Something("fource"), | ||||
| 			Expected: opt.Something[int](6), | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for testNumber, test := range tests { | ||||
| 
 | ||||
| 		fn := func(s string) int { | ||||
| 			return len(s) | ||||
| 		} | ||||
| 
 | ||||
| 		mapped := opt.Map(test.Optional, fn) | ||||
| 
 | ||||
| 		{ | ||||
| 			expected := test.Expected | ||||
| 			actual   := mapped | ||||
| 
 | ||||
| 			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 | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
		Loading…
	
		Reference in New Issue