v/vlib/v/tests/if_smartcast_test.v

312 lines
4.0 KiB
V

struct Abc {
mut:
val string
}
struct Xyz {
name string
}
type Alphabet = Abc | Xyz
fn test_if_smartcast() {
x := Alphabet(Abc{'test'})
if x is Abc {
assert x.val == 'test'
}
}
fn test_mutable() {
mut x := Alphabet(Abc{'original'})
if mut x is Abc {
assert x.val == 'original'
x.val = 'changed'
assert x.val == 'changed'
}
if mut x is Abc {
assert x.val == 'changed'
}
}
fn test_nested_if_smartcast() {
x := Alphabet(Abc{'test'})
y := Alphabet(Xyz{'foo'})
if x is Abc {
if y is Xyz {
assert y.name == 'foo'
}
}
}
type Bar = Test | string
type Xya = int | string
struct Test {
x string
xya Xya
}
struct BarWrapper {
y Bar
}
fn test_nested_selector_smartcast() {
f := BarWrapper{
y: Bar(Test{
x: 'Hi'
xya: Xya(int(5))
})
}
if f.y is Test {
z := f.y.x
assert f.y.x == 'Hi'
assert z == 'Hi'
if f.y.xya is int {
assert f.y.xya == 5
}
}
}
type Inner = int | string
struct InnerStruct {
x Inner
}
type Outer = InnerStruct | string
fn test_nested_if_is() {
b := Outer(InnerStruct{Inner(0)})
if b is InnerStruct {
if b.x is int {
assert b.x == 0
}
}
}
struct MutContainer {
mut:
abc Alphabet
}
struct Container {
abc Alphabet
}
fn test_mutable_with_struct() {
mut c := MutContainer{Abc{'original'}}
if mut c.abc is Abc {
assert c.abc.val == 'original'
c.abc.val = 'xyz'
assert c.abc.val == 'xyz'
}
if mut c.abc is Abc {
// NB: in this second smart cast, `another` is
// the same wrapped value, that was changed in
// the first smart cast:
assert c.abc.val == 'xyz'
}
}
fn test_as_cast_with_struct() {
x := Container{Abc{'test'}}
if x.abc is Abc {
assert x.abc.val == 'test'
}
}
struct CellStr {
str string
}
struct CellInt {
itg i64
}
struct CellFloat {
flt f64
}
struct CellU32 {
u u32
}
type Cell = CellFloat | CellInt | CellStr | CellU32
fn test_mutability() {
my_str := 'the quick brown fox jumps over the lazy dog.'
my_itg := -1234567890
my_flt := 3.14159265358979323846
my_u32 := u32(4294967295)
cell_str := CellStr{
str: my_str
}
cell_itg := CellInt{
itg: my_itg
}
cell_flt := CellFloat{
flt: my_flt
}
cell_u32 := CellU32{
u: my_u32
}
mut cell := Cell{}
cell = cell_str
if mut cell is CellStr {
println('$cell.str')
}
cell = cell_itg
if mut cell is CellInt {
println('$cell.itg')
}
cell = cell_flt
if mut cell is CellFloat {
println('$cell.flt')
}
cell = cell_u32
if mut cell is CellU32 {
println('$cell.u')
}
}
type Expr = CTempVarExpr | CallExpr
struct ExprWrapper {
mut:
expr Expr
}
struct CallExpr {
y int
x string
}
struct CTempVarExpr {
x string
}
fn gen(_ Expr) CTempVarExpr {
return CTempVarExpr{}
}
fn test_reassign_from_function_with_parameter_selector() {
mut f := ExprWrapper{Expr(CallExpr{})}
if f.expr is CallExpr {
f.expr = gen(f.expr)
}
}
type Node = Expr | string
fn test_nested_sumtype() {
c := Node(Expr(CallExpr{
y: 1
}))
if c is Expr {
if c is CallExpr {
assert c.y == 1
} else {
assert false
}
} else {
assert false
}
}
type Food = Eggs | Milk
struct FoodWrapper {
mut:
food Food
}
struct Milk {
mut:
name string
}
struct Eggs {
mut:
name string
}
fn test_if_mut_selector() {
mut f := FoodWrapper{Food(Milk{'test'})}
if mut f.food is Milk {
f.food.name = 'milk'
assert f.food.name == 'milk'
}
}
struct NodeWrapper {
node Node
}
fn test_nested_sumtype_selector() {
c := NodeWrapper{Node(Expr(CallExpr{
y: 1
}))}
if c.node is Expr {
if c.node is CallExpr {
assert c.node.y == 1
} else {
assert false
}
} else {
assert false
}
}
struct Foo1 {
a int
}
struct Foo2 {
a int
}
struct Bar1 {
a int
}
struct Bar2 {
a int
}
type Sum1 = Foo1 | Foo2
type Sum2 = Bar1 | Bar2
type SumAll = Sum1 | Sum2
struct All_in_one {
pub mut:
ptrs []&SumAll
ptr &SumAll
}
fn test_nested_pointer_smartcast() {
mut s := All_in_one{
ptr: &Sum1(Foo1{
a: 1
})
ptrs: [&SumAll(Sum2(Bar1{
a: 3
}))]
}
if mut s.ptr is Sum1 {
if mut s.ptr is Foo1 {
assert s.ptr.a == 1
}
}
a := s.ptrs[0]
if a is Sum1 {
if a is Foo1 {
assert a.a == 3
}
}
}