// WARNING: This file is machine generated by fidlgen_dart.
// @dart = 2.12

library fidl_fidl_test_struct_async;

import 'dart:async' as $async;
import 'dart:core' hide Set;
import 'dart:developer';
import 'dart:typed_data';

import 'package:fidl/fidl.dart' as $fidl;
import 'package:meta/meta.dart';
import 'package:zircon/zircon.dart' as $zircon;

// ignore_for_file: always_specify_types
// ignore_for_file: avoid_positional_boolean_parameters
// ignore_for_file: avoid_returning_null
// ignore_for_file: cascade_invocations
// ignore_for_file: constant_identifier_names
// ignore_for_file: one_member_abstracts
// ignore_for_file: prefer_constructors_over_static_methods
// ignore_for_file: prefer_single_quotes
// ignore_for_file: public_member_api_docs
// ignore_for_file: unused_import
// ignore_for_file: unused_local_variable
// ignore_for_file: non_constant_identifier_names
// ignore_for_file: library_prefixes
// ignore_for_file: prefer_typing_uninitialized_variables
// ignore_for_file: avoid_js_rounded_ints
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: prefer_generic_function_type_aliases
// ignore_for_file: prefer_equal_for_default_values
// ignore_for_file: avoid_catches_without_on_clauses
// ignore_for_file: unused_shown_name
// ignore_for_file: unnecessary_lambdas
// ignore_for_file: comment_references
// ignore_for_file: avoid_unused_constructor_parameters
// ignore_for_file: prefer_interpolation_to_compose_strings

class Simple extends $fidl.Struct {
  const Simple({
    required this.f1,
    required this.f2,
  });
  Simple.clone(
    Simple $orig, {
    int? f1,
    bool? f2,
  }) : this(
          f1: f1 ?? $orig.f1,
          f2: f2 ?? $orig.f2,
        );

  final int f1;
  final bool f2;

  @override
  List<Object?> get $fields {
    return <Object?>[
      f1,
      f2,
    ];
  }

  static const $fieldType0 = $fidl.Uint8Type();
  static const $fieldType1 = $fidl.BoolType();

  @override
  void $encode($fidl.Encoder $encoder, int $offset, int $depth) {
    $fieldType0.encode($encoder, f1, $offset + 0, $depth);
    $fieldType1.encode($encoder, f2, $offset + 1, $depth);
  }

  @override
  String toString() {
    return r'Simple' r'(f1: ' +
        f1.toString() +
        r', f2: ' +
        f2.toString() +
        r')';
  }

  static Simple _structDecode($fidl.Decoder $decoder, int $offset, int $depth) {
    return Simple(
        f1: $fieldType0.decode($decoder, $offset + 0, $depth),
        f2: $fieldType1.decode($decoder, $offset + 1, $depth));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Simple> kSimple_Type = $fidl.StructType<Simple>(
  inlineSize: 2,
  structDecode: Simple._structDecode,
);

class BasicStruct extends $fidl.Struct {
  const BasicStruct({
    required this.x,
    required this.y,
  });
  BasicStruct.clone(
    BasicStruct $orig, {
    int? x,
    String? y,
  }) : this(
          x: x ?? $orig.x,
          y: y ?? $orig.y,
        );

  final int x;
  final String y;

  @override
  List<Object?> get $fields {
    return <Object?>[
      x,
      y,
    ];
  }

  static const $fieldType0 = $fidl.Uint32Type();
  static const $fieldType1 = $fidl.StringType(maybeElementCount: null);

  @override
  void $encode($fidl.Encoder $encoder, int $offset, int $depth) {
    $fieldType0.encode($encoder, x, $offset + 0, $depth);
    $fieldType1.encode($encoder, y, $offset + 8, $depth);
  }

  @override
  String toString() {
    return r'BasicStruct' r'(x: ' +
        x.toString() +
        r', y: ' +
        y.toString() +
        r')';
  }

  static BasicStruct _structDecode(
      $fidl.Decoder $decoder, int $offset, int $depth) {
    return BasicStruct(
        x: $fieldType0.decode($decoder, $offset + 0, $depth),
        y: $fieldType1.decode($decoder, $offset + 8, $depth));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<BasicStruct> kBasicStruct_Type =
    $fidl.StructType<BasicStruct>(
  inlineSize: 24,
  structDecode: BasicStruct._structDecode,
);

// ignore: unused_element, avoid_private_typedef_functions
typedef _VoidCallback = void Function();
