# Codec

Encoding and decoding are done as per [the fuel spec](https://docs.fuel.network/docs/specs/abi/argument-encoding/). To this end, `fuels` makes use of the [`ABIEncoder`](https://docs.rs/fuels/latest/fuels/core/codec/struct.ABIEncoder.html) and the [`ABIDecoder`](https://docs.rs/fuels/latest/fuels/core/codec/struct.ABIDecoder.html).

## Prerequisites for decoding/encoding

To encode a type, you must first convert it into a [`Token`](https://docs.rs/fuels/latest/fuels/types/enum.Token.html). This is commonly done by implementing the [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html) trait.

To decode, you also need to provide a [`ParamType`](https://docs.rs/fuels/latest/fuels/types/param_types/enum.ParamType.html) describing the schema of the type in question. This is commonly done by implementing the [Parameterize](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html) trait.

All types generated by the [`abigen!`](../abigen/index.md) macro implement both the [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html) and [`Parameterize`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html) traits.

`fuels` also contains implementations for:

- [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html) for the `fuels`-owned types listed [here](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html#implementors) as well as [for some foreign types](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html#foreign-impls) (such as `u8`, `u16`, `std::vec::Vec<T: Tokenizable>`, etc.).
- [`Parameterize`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html) for the `fuels`-owned types listed [here](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html#implementors) as well as [for some foreign types](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html#foreign-impls) (such as `u8`, `u16`, `std::vec::Vec<T: Parameterize>`, etc.).

## Deriving the traits

Both [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html) and [`Parameterize`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html) can be derived for `struct`s and `enum`s if all inner types implement the derived traits:

```rust,ignore
        use fuels::macros::{Parameterize, Tokenizable};

        #[derive(Parameterize, Tokenizable)]
        struct MyStruct {
            field_a: u8,
        }

        #[derive(Parameterize, Tokenizable)]
        enum SomeEnum {
            A(MyStruct),
            B(Vec<u64>),
        }
            #[derive(Parameterize, Tokenizable)]
            #[FuelsCorePath = "fuels_core_elsewhere"]
            #[FuelsTypesPath = "fuels_types_elsewhere"]
            pub struct SomeStruct {
                field_a: u64,
            }
            use fuels::macros::{Parameterize, Tokenizable};
            #[derive(Parameterize, Tokenizable)]
            #[NoStd]
            pub struct SomeStruct {
                field_a: u64,
            }
```

> Note:
> Deriving [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html) on `enum`s requires that all variants also implement [`Parameterize`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html).

### Tweaking the derivation

#### Changing the location of imports

The derived code expects that the `fuels` package is accessible through `::fuels`. If this is not the case then the derivation macro needs to be given the locations of `fuels::types` and `fuels::core`.

```rust,ignore
            #[derive(Parameterize, Tokenizable)]
            #[FuelsCorePath = "fuels_core_elsewhere"]
            #[FuelsTypesPath = "fuels_types_elsewhere"]
            pub struct SomeStruct {
                field_a: u64,
            }
```

#### Generating no-std code

If you want `no-std` generated code:

```rust,ignore
            use fuels::macros::{Parameterize, Tokenizable};
            #[derive(Parameterize, Tokenizable)]
            #[NoStd]
            pub struct SomeStruct {
                field_a: u64,
            }
```
