# Structs and enums

<!-- This section should explain how to get the custom types from a Sway program -->
<!-- custom_types:example:start -->
The structs and enums you define in your Sway code have equivalents automatically generated by the SDK's `abigen!` macro.
<!-- custom_types:example:end -->

For instance, if in your Sway code you have a struct called `CounterConfig` that looks like this:

```rust,ignore
struct CounterConfig {
  dummy: bool,
  initial_value: u64,
}
```

After using the `abigen!` macro, `CounterConfig` will be accessible in your Rust file! Here's an example:

```rust,ignore
    abigen!(Contract(
        name = "MyContract",
        abi = "e2e/sway/types/contracts/complex_types_contract/out/release/complex_types_contract-abi.json"
    ));

    // Here we can use `CounterConfig`, a struct originally
    // defined in the contract.
    let counter_config = CounterConfig {
        dummy: true,
        initial_value: 42,
    };
```

You can freely use your custom types (structs or enums) within this scope. That also means passing custom types to functions and receiving custom types from function calls.

## Generics

The Fuel Rust SDK supports both generic enums and generic structs. If you're already familiar with Rust, it's your typical `struct MyStruct<T>` type of generics support.

For instance, your Sway contract could look like this:

```Rust
contract;

use std::hash::sha256;

struct SimpleGeneric<T> {
    single_generic_param: T,
}

abi MyContract {
  fn struct_w_generic(arg1: SimpleGeneric<u64>) -> SimpleGeneric<u64>;
}

impl MyContract for Contract {
    fn struct_w_generic(arg1: SimpleGeneric<u64>) -> SimpleGeneric<u64> {
        let expected = SimpleGeneric {
            single_generic_param: 123u64,
        };

        assert(arg1.single_generic_param == expected.single_generic_param);

        expected
    }
}
```

Your Rust code would look like this:

```rust,ignore
        // simple struct with a single generic param
        let arg1 = SimpleGeneric {
            single_generic_param: 123u64,
        };

        let result = contract_methods
            .struct_w_generic(arg1.clone())
            .call()
            .await?
            .value;

        assert_eq!(result, arg1);
```

### Unused generic type parameters

Sway supports unused generic type parameters when declaring structs/enums:

```Rust
struct SomeStruct<T, K> {
  field: u64
}

enum SomeEnum<T, K> {
  One: u64
}

```

If you tried the same in Rust you'd get complaints that `T` and `K` must be used or removed. When generating Rust bindings for such types we make use of the [`PhantomData`](https://doc.rust-lang.org/std/marker/struct.PhantomData.html#unused-type-parameters) type. The generated bindings for the above example would look something like this:

```Rust
struct SomeStruct<T, K> {
   pub field: u64,
   pub _unused_generic_0: PhantomData<T>
   pub _unused_generic_1: PhantomData<K>
}

enum SomeEnum<T, K> {
  One(u64),
  IgnoreMe(PhantomData<T>, PhantomData<K>)
}
```

To lessen the impact to developer experience you may use the `new` method to initialize a structure without bothering with the `PhantomData`s.:

```rust,ignore
        assert_eq!(
            <StructUnusedGeneric<u16, u32>>::new(15),
            StructUnusedGeneric {
                field: 15,
                _unused_generic_0: std::marker::PhantomData,
                _unused_generic_1: std::marker::PhantomData
            }
        );
```

If your struct doesn't have any fields we'll also derive `Default`. As for enums all `PhantomData`s are placed inside a new variant called `IgnoreMe` which you'll need to ignore in your matches:

```rust,ignore
        match my_enum {
            EnumUnusedGeneric::One(_value) => {}
            EnumUnusedGeneric::IgnoreMe(..) => panic!("Will never receive this variant"),
        }
```
