Skip to main content

Convert

Derive Macro Convert 

Source
#[derive(Convert)]
{
    // Attributes available to this derive:
    #[convert]
}
Expand description

§derive-into

For more information, visit the github repository.

A derive macro for creating conversions between structs and enums with similar structures.

This crate provides the #[derive(Convert)] macro that automates implementations of conversion traits (From, Into, TryFrom, TryInto) between types.

§Basic Usage

use derive_into::Convert;

#[derive(Convert)]
#[convert(into(path = "Destination"))]
struct Source {
    id: u32,
    #[convert(rename = "full_name")]
    name: String,
}

struct Destination {
    id: u32,
    full_name: String,
}

// Usage: let destination: Destination = source.into();

§Attribute Reference

§Struct/Enum Level Attributes

AttributeDescription
#[convert(into(path = "Type"))]Implements From<Self> for Type
#[convert(from(path = "Type"))]Implements From<Type> for Self
#[convert(try_into(path = "Type"))]Implements TryFrom<Self> for Type
#[convert(try_from(path = "Type"))]Implements TryFrom<Type> for Self

Multiple conversion attributes can be specified for a single type:

use derive_into::Convert;

struct ApiModel {
    version: String,
    name: String,
}

struct DbModel {
    version: String,
    name: String,
}

#[derive(Convert)]
#[convert(into(path = "ApiModel"))]
#[convert(try_from(path = "DbModel"))]
struct DomainModel {
    version: String,
    name: String,
}

§Field Level Attributes

Field attributes can be applied at three different scopes:

  1. Global scope - applies to all conversions
#[convert(rename = "new_name")]
  1. Conversion type scope - applies to a specific conversion type
#[convert(try_from(skip))]
  1. Specific conversion scope - applies to a specific conversion path
#[convert(try_from(path = "ApiModel", skip))]
AttributeDescription
#[convert(rename = "new_name")]Maps field to different name in target
#[convert(skip)]Excludes field from conversion
#[convert(default)]Uses Default::default() for this field
#[convert(unwrap)]Unwraps Option (try_from fails if None)
#[convert(unwrap_or_default)]Automatically calls unwrap_or_default on Option value before converting it
#[convert(with_func = "func_name")]Uses custom conversion function

§Custom Conversion Functions

Functions specified with with_func must accept a reference to the source type:

use derive_into::Convert;

struct ValidatedType(String);

struct ApiModel {
   field: String,
}

#[derive(Convert)]
#[convert(try_from(path = "ApiModel"))]
struct Product {
    #[convert(try_from(rename = "field", with_func = "validate_field"))]
    validated: ValidatedType,
}

fn validate_field(source: &ApiModel) -> Result<ValidatedType, String> {
   Ok(ValidatedType(source.field.clone()))
}

§Type Conversion Behavior

  • Direct mapping: Identical types are copied directly
  • Automatic conversion: Uses From/Into for different types
  • Container types: Handles Option<T>, Vec<T>, and HashMap<K,V>
  • Nested conversions: Converts nested structs/enums automatically

§Container Type Examples

§Option and Vec

use derive_into::Convert;

struct Number(u8);
impl From<u8> for Number {
    fn from(n: u8) -> Self {
        Number(n)
    }
}

#[derive(Convert)]
#[convert(into(path = "Target"))]
struct Source {
    // Inner type u8 -> Number conversion happens automatically
    optional: Option<u8>,
    vector: Vec<u8>,
}

struct Target {
    optional: Option<Number>, // Number implements From<u8>
    vector: Vec<Number>,
}

§HashMap

use derive_into::Convert;
use std::collections::HashMap;

#[derive(Hash, Eq, PartialEq)]
struct CustomString(String);

impl From<String> for CustomString {
    fn from(s: String) -> Self {
        CustomString(s)
    }
}

struct CustomInt(u32);

impl From<u32> for CustomInt {
    fn from(i: u32) -> Self {
        CustomInt(i)
    }
}

#[derive(Convert)]
#[convert(into(path = "Target"))]
struct Source {
    // Both keys and values convert if they implement From/Into
    map: HashMap<String, u32>,
}

struct Target {
    map: HashMap<CustomString, CustomInt>,
}

§Enum Conversion

use derive_into::Convert;

#[derive(Convert)]
#[convert(into(path = "TargetEnum"))]
enum SourceEnum {
    Variant1(u32),
    #[convert(rename = "RenamedVariant")]
    Variant2 {
        value: String,
        #[convert(rename = "renamed_field")]
        field: u8,
    },
    Unit,
}

enum TargetEnum {
    Variant1(u32),
    RenamedVariant {
        value: String,
        renamed_field: u8,
    },
    Unit,
}

Derive macro for generating conversion implementations between similar types.

The Convert derive macro generates implementations of standard conversion traits (From, Into, TryFrom, TryInto) between structs and enums with similar structures.

§Examples

Basic struct conversion with field renaming:

use derive_into::Convert;

#[derive(Convert)]
#[convert(into(path = "Destination"))]
struct Source {
    id: u32,
    #[convert(rename = "full_name")]
    name: String,
}

struct Destination {
    id: u32,
    full_name: String,
}