Rust-Property

![License] ![GitHub Actions] ![Crate Badge] ![Crate Doc] ![MSRV 1.31.0]

Generate several common methods for structs automatically.

Usage

Apply the derive proc-macro #[derive(Property)] to structs, and use #[property(..)] to configure it.

There are three levels of properties:

If no properties is set, the default properties will be applied:

```rust

[property(

get(crate, prefix = "", suffix = "", type="auto"),
set(crate, prefix = "set_", type = "ref"),
mut(crate, prefix = "mut_"),
clr(crate, prefix = "clear_", scope = "option")
ord(asc)

)] ```

There are six kinds of configurable properties: skip, get, set, mut, clr and ord.

In Action

Original Code

```rust

![no_std]

[cfg(not(feature = "std"))]

extern crate alloc;

[cfg(feature = "std")]

extern crate std as alloc;

use alloc::{string::String, vec::Vec};

use property::{property_default, Property};

[property_default(get(public), ord(desc), clr(scope = "option"))]

struct PropertyCrateConf;

[derive(Copy, Clone)]

pub enum Species { Dog, Cat, Bird, Other, }

[derive(Property)]

[property(set(private), mut(disable))]

pub struct Pet { #[property(get(name = "identification"), set(disable), ord(asc, 2))] id: [u8; 32], name: String, #[property(set(crate, type = "own"), ord(0))] age: u32, #[property(get(type = "copy"))] species: Species, #[property(get(prefix = "is"), ord(1))] died: bool, #[property(get(type = "clone"), set(type = "none"))] owner: String, #[property(clr(scope = "auto"))] familymembers: Vec, #[property(get(type = "ref"), mut(crate))] info: String, #[property(get(disable), set(type = "replace"))] pub tag: Vec, #[property(mut(public, suffix = "mut"))] note: Option, #[property(set(type = "replace", full_option))] price: Option, #[property(skip)] pub reserved: String, } ```

Generated Code

rust impl Pet { #[inline] pub fn identification(&self) -> &[u8] { &self.id[..] } #[inline] pub fn name(&self) -> &str { &self.name[..] } #[inline] fn set_name<T: Into<String>>(&mut self, val: T) -> &mut Self { self.name = val.into(); self } #[inline] pub fn age(&self) -> u32 { self.age } #[inline] pub(crate) fn set_age<T: Into<u32>>(mut self, val: T) -> Self { self.age = val.into(); self } #[inline] pub fn species(&self) -> Species { self.species } #[inline] fn set_species<T: Into<Species>>(&mut self, val: T) -> &mut Self { self.species = val.into(); self } #[inline] pub fn is_died(&self) -> bool { self.died } #[inline] fn set_died<T: Into<bool>>(&mut self, val: T) -> &mut Self { self.died = val.into(); self } #[inline] pub fn owner(&self) -> String { self.owner.clone() } #[inline] fn set_owner<T: Into<String>>(&mut self, val: T) { self.owner = val.into(); } #[inline] pub fn family_members(&self) -> &[String] { &self.family_members[..] } #[inline] fn set_family_members<T: Into<String>>( &mut self, val: impl IntoIterator<Item = T>, ) -> &mut Self { self.family_members = val.into_iter().map(Into::into).collect(); self } #[inline] pub(crate) fn clear_family_members(&mut self) { self.family_members.clear(); } #[inline] pub fn info(&self) -> &String { &self.info } #[inline] fn set_info<T: Into<String>>(&mut self, val: T) -> &mut Self { self.info = val.into(); self } #[inline] pub(crate) fn mut_info(&mut self) -> &mut String { &mut self.info } #[inline] fn set_tag<T: Into<String>>(&mut self, val: impl IntoIterator<Item = T>) -> Vec<String> { ::core::mem::replace(&mut self.tag, val.into_iter().map(Into::into).collect()) } #[inline] pub fn note(&self) -> Option<&String> { self.note.as_ref() } #[inline] fn set_note<T: Into<String>>(&mut self, val: T) -> &mut Self { self.note = Some(val.into()); self } #[inline] pub fn note_mut(&mut self) -> &mut Option<String> { &mut self.note } #[inline] pub(crate) fn clear_note(&mut self) { self.note = None; } #[inline] pub fn price(&self) -> Option<u32> { self.price } #[inline] fn set_price<T: Into<Option<u32>>>(&mut self, val: T) -> Option<u32> { ::core::mem::replace(&mut self.price, val.into()) } #[inline] pub(crate) fn clear_price(&mut self) { self.price = None; } } impl PartialEq for Pet { fn eq(&self, other: &Self) -> bool { self.age == other.age && self.died == other.died && self.id == other.id } } impl PartialOrd for Pet { fn partial_cmp(&self, other: &Self) -> Option<::core::cmp::Ordering> { let result = other.age.partial_cmp(&self.age); if result != Some(::core::cmp::Ordering::Equal) { return result; } let result = other.died.partial_cmp(&self.died); if result != Some(::core::cmp::Ordering::Equal) { return result; } let result = self.id.partial_cmp(&other.id); if result != Some(::core::cmp::Ordering::Equal) { return result; } Some(::core::cmp::Ordering::Equal) } }

Enjoy it!

Minimum Supported Rust Version

[Rust 1.31.0].

License

Licensed under either of [Apache License, Version 2.0] or [MIT License], at your option.