// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library fidl.rust.test.compilation;

using zx;

type TestXUnion = flexible union {
    1: variant bool;
};

type ErrorReturn = strict enum : uint32 {
    OK = 0x00;
    CHANGED = 0x0D;
};

const ERROR_RETURN_CONST ErrorReturn = ErrorReturn.OK;

protocol TestInterface {
    TestMethod(struct {
        test_x_union TestXUnion;
    }) -> (struct {
        test_x_union TestXUnion;
    });
    TestNullableXUnion(struct {
        test_x_union TestXUnion:optional;
    }) -> (struct {
        test_x_union TestXUnion:optional;
    });
    TestErrorMethod(struct {
        arg uint16;
    }) -> (struct {}) error ErrorReturn;
    // TODO(fxbug.dev/59947): add "responder" and "control_handle"
    TestNameClashesTwoWay(resource struct {
        bytes bytes;
        handles vector<zx.handle>;
        header string;
    }) -> (resource struct {
        bytes bytes;
        handles vector<zx.handle>;
        header string;
    });
    TestNameClashesOneWay(resource struct {
        bytes bytes;
        handles vector<zx.handle>;
        header string;
    });
    -> TestNameClashesEvent(resource struct {
        bytes bytes;
        handles vector<zx.handle>;
        header string;
    });
};

type HasBigArray = struct {
    big_arr array<uint8, 256>;
};

type HasStructWithBigArray = strict union {
    1: variant HasBigArray;
    2: variant2 uint8;
};

type Result = struct {
    ensure_that_type_named_result_compiles string;
};

type HasHostFidlHandleStubbing = resource struct {
    log zx.handle:LOG;
};
