[][src]Crate born

Reuse(Struct, Enum)

It provides functional macros to reuse fields from Struct and Enum definition.

[dependencies]
born = "0.0.0"

Examples

Struct

Say you build a demo web server to send private messages.

use born::{
   nested_macro,
   public_struct,
};

// Define your base public struct here.
public_struct!(
    // pub is required here before struct
    pub struct MessageBase {
        pub text: String
        // pub text: String // , is not required for the struct definition.
    }
);

MessageBase!(
    #[derive(Debug, Clone, PartialEq)]
    pub struct Message {
        pub read: bool,
        // read: bool, // pub is optional.
    }
);

impl Message {
    fn update_text(&mut self, new_message: String) {
        self.text = new_message
    }
    fn read(&mut self) {
        if self.read == false {
           self.read = true;
       }
   }
}

MessageBase!(
   #[derive(Debug, Clone, PartialEq)]
   pub struct MessageCreateRequest
);

MessageBase!(
    // #[derive(Debug, Clone, PartialEq)]
    pub struct MessageUpdateRequest
);

fn main() {
    let message_create_request = MessageCreateRequest {
        text: "I am Steadylearner and 'born' is the crate name.".into(),
    };

    let mut message = Message {
        text: message_create_request.text,
        read: false,
    };
    println!("{:#?}", &message);

    assert_eq!(message, message.clone());

    let message_update_request = MessageUpdateRequest {
        text: "Reuse fields with macros from 'born'.".into(),
    };

    message.update_text(message_update_request.text);
    println!("{:#?}", &message);

    message.read();
    println!("{:#?}", &message);
}

Enum

Compare it with the code example from the Rust documenation for Enum.

use born::{
    nested_macro,
    private_enum,
};

// Define your base private enum here.
private_enum!(
    enum WebEventBase {
        PageLoad,
        PageUnload, // , here is required if you want to extend it.
    }
);

WebEventBase!(
    // #[derive(Debug, Clone, PartialEq)]
    enum WebEvent {
        KeyPress(char),
        Click { x: i64, y: i64 },
        Paste(String),
    }
);

fn inspect(event: WebEvent) {
    match event {
        WebEvent::PageLoad => println!("page loaded"),
        WebEvent::PageUnload => println!("page unloaded"),
        WebEvent::KeyPress(c) => println!("pressed '{}'.", c),
        WebEvent::Paste(s) => println!("pasted \"{}\".", s),
        WebEvent::Click { x, y } => {
            println!("clicked at x={}, y={}.", x, y);
        },
    }
}

fn main() {
    let pressed = WebEvent::KeyPress('x');
    let pasted  = WebEvent::Paste("my text".to_owned());
    let click   = WebEvent::Click { x: 20, y: 80 };
    let load    = WebEvent::PageLoad;
    let unload  = WebEvent::PageUnload;

    inspect(pressed);
    inspect(pasted);
    inspect(click);
    inspect(load);
    inspect(unload);
}

Rename

You can rename struct and enum and reuse the exact same fields.

use born::{
    nested_macro,
    public_struct,
};

public_struct!(
    pub struct UserBase {
        pub first_name: String,
        pub last_name: String,
        pub email: String,
        pub password: String,
    }
);

UserBase!(
    pub struct User {
        pub id: i64,
    }
);

UserBase!(
    pub struct NewUser
);

// It is equal to code it manually.

// pub struct User {
//     pub id: i64,
//     pub first_name: String,
//     pub last_name: String,
//     pub email: String,
//     pub password: String,
// }

// pub struct NewUser {
//     pub first_name: String,
//     pub last_name: String,
//     pub email: String,
//     pub password: String,
// }

Details

  • Each struct and enum created from the macros are completely unrelevant to each other except they have the same fields you define.

  • When you use private_struct! and private_enum!, you can't use pub keyword in it and others use them. It wouldn't be logical if a private struct or private enum can have public fields.

  • nested_macro! is required to use the other macros from this crate. It is used to make a macro that creates other macros.

macro_rules! nested_macro {
    ($($body:tt)*) => {
        macro_rules! __nested_macro { $($body)+ }
        __nested_macro!($);
    }
}

Comparison with attribute macros

Macros

nested_macro

You can make a macro that creates other macros with it.

private_enum

Use it to to create, extend and reuse fields from private enum definition.

private_struct

Use it to to create, extend and reuse fields from private struct definition.

public_enum

Similar to private_enum! but public.

public_struct

Similar to private_struct! but public.