v/vlib/v/tests/generic_sumtype_test.v

79 lines
1.3 KiB
V

struct None {}
// not named `Option` to avoid conflicts with the built-in type:
type MyOption<T> = Error | None | T
fn unwrap_if<T>(o MyOption<T>) T {
if o is T {
return o
}
panic('no value')
}
fn unwrap_match<T>(o MyOption<T>) string {
match o {
None {
return 'none'
}
Error {
return 'none'
}
T {
return 'value'
}
}
}
fn test_generic_sumtype_unwrapping() {
y := MyOption<bool>(false)
assert unwrap_if(y) == false
assert unwrap_match(y) == 'value'
}
fn test_generic_sumtype_auto_str() {
x := MyOption<string>('hi')
y := MyOption<bool>(None{})
assert '$x, $y' == "MyOption<string>('hi'), MyOption<bool>(None{})"
}
struct Foo<T> {
x T
}
struct Bar<T> {
x T
}
type MyType<T> = Bar<T> | Foo<T>
fn test_generic_struct_members() {
// TODO: this is currently needed to properly resolve that variant's type:
_ = Bar<string>{''}
f := Foo<string>{'hi'}
t := MyType<string>(f)
assert t.type_name() == 'Foo<string>'
// accessing a field common to all variants, just like with a normal sumtype:
assert t.x == 'hi'
}
type MultiGeneric<X, Y, Z> = X | Y | Z
fn test_multi_generic_type() {
mut m := MultiGeneric<bool, int, string>(1234)
m = 'hi'
match m {
bool {
assert false
}
int {
assert false
}
string {
return
}
}
assert false
}