312 lines
4.0 KiB
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 {
|
|
// Note: 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
|
|
}
|
|
}
|
|
}
|