Expand description
This package provides a coherent set of manual accessor macros.
While a number of packages exist to simplify the addition of accessors to Rust structures and enumerations
these are often derive macros that come with a trade-off between flexibility and control. Jemmy takes a
different and more flexible approach. It provides a set of very simple leaf macros and then aggregate
macros that build common patterns from these building blocks. For example, you can add get_and_set
methods for a simple field, or with_get_and_set to include an initializer as well. You can use the
get_set_and_unset for optional fields which produces foo() -> Option<&T>, set_foo(T), and unset_foo()
methods rather than a setter that takes an Option<T>.
In general most users will use the combination macros such as with_get_and_set or get_set_and_unset;
however, as these are directly built upon the individual accessor macros get, set, unset, with,
and so forth it becomes easy to customize the set of methods a type provides.
The name Jemmy was chosen for this crate as the common name for a small pry-bar or crowbar used in burglary, a very direct form of manual access.
§Example 1 - Structures
The following shows the basics of the macros for generating accessors for the fields of a structure. This
will provide initializers, getters and setters for the number_on_street and street_1 fields. A getter,
setter (value) and unsetter (None) will be provided for the street_2 field.
use jemmy::*;
#[derive(Default)]
pub struct Address {
number_on_street: u32,
street_1: String,
street_2: Option<String>,
// ...
}
impl Address {
with!(pub number_on_street => u32);
get!(pub number_on_street => copy u32);
set!(pub number_on_street => u32);
with_get_and_set!(pub street_1 => into String);
get_set_and_unset!(pub street_2 => String);
}Typically here’s the constructor rules of thumb:
- If an instance can be generated by default (actually
Default) it should. - If not, or for explicit construction, anything required for construction should be a parameter
to a
newornew_associated function that either returnsSelforResult<Self, Error>. - Optional things that initialize an instance before use but after construction should have a
with_method. - Anything else should have a getter and setter (and maybe un-setter) method.
One way to combine a builder-like pattern into a type rather than have a separate type (if doing so adds no significant value) is to separate the notion of construction and initialization as the list above does. Thus, construction is the process of creating an instance, initialization ensures that instance is in a valid state and ready to use. For example, in the following the construction process does not raise errors because all it does is verifies the existence of a vehicle. The initialization process on the other hand may result in errors.
let car: Car = Default::default()
.with_vin(MY_CAR_VEHICLE_ID_NUMBER),
.with_fuel(Capacity::Full),
.initialize()?;
assert_eq!(car.vin(), MY_CAR_VEHICLE_ID_NUMBER);
assert_eq!(car.make(), "Subaru");§Example 2 - Enums
The following shows the basics of the macros for generating accessors for the variants of an enum. For
each variant an is_variant predicate and as_variant cast methods are provided.
use jemmy::*;
pub enum TypedAddress {
Home(Address),
Work(Address),
Other(Address),
}
impl TypedAddress {
is_variant!(Home => Address);
as_variant!(Home => Address);
is_as_variant!(Work => Address);
is_as_variant!(Other => Address);
}§Standard Forms
The following are the primary forms supported by the macros in the crate; the first is the form of all field macros, the second is the form of all variant macros.
(viz Name [, function_name] => [ field_name, ] [ keywords ] [ Type ])(viz Variant [, function_name] [ => Type ])
The elements of these forms are described below.
- viz; the vizibility specifier for the generated method.
- for field macros:
- Name; the public name of the field, this will be the core name of the method with any prefix/suffix required.
- function_name; (optional) where the method name needs to be overridden on a per-method basis this allows for the specification of the core name of the method.
- field name; (optional) when the visible name of the field is different from its field name you may specify both.
- keywords (optional):
- copy; denotes that the field type implements
Copyand the generatted method will return a value rather than a reference. - into; will generate a setter method that takes a parameter of type
Into<T>rather than the typicalT. - optional; denotes that the field is an
Option<T>notTwhich affects all getters and setters.
- copy; denotes that the field type implements
- Type; (optional) the type of the field, specifically
T, do not specifyOption<T>orInto<T>if using the corresponding keywords.
- for enum macros:
- Variant; the variant’s identifier within the enum.
- function_name; (optional) where the method name needs to be overridden on a per-method basis this allows for the specification of the core name of the method.
- keywords (optional):
- copy; denotes that the field type implements
Copyand the generatted method will return a value rather than a reference. - value; TBD (const).
- copy; denotes that the field type implements
- Type; (optional) the type of any value of the variant.
Modules§
Macros§
- as_
variant - Generate a safe cast method for variant-associated data.
- get
- Generate a getter method for a field within a structure.
- get_
and_ set - Generate
getandsetfor a struct field. - get_mut
- Generate a mutable getter method for a struct field.
- get_
set_ and_ unset - Generate
get,set, andunsetfor an optional struct field. - impl_
from_ for_ variant - Generate an implementation of the standard From trait to construct a new enum with the provided variant value.
- is_
as_ variant - Generate both
is_variantandas_variantfor an enumeration variant. - is_
variant - Generate a predicate function that returns
trueif the instance of the corresponding enumeration is of the given variant. - set
- Generate a setter method for a field within a structure.
- unset
- Generate an un-setter method for an optional struct field.
- with
- Generate a builder style initializer method for a struct field.
- with_
get_ and_ set - Generate
with,getandsetfor a struct field. - with_
get_ set_ and_ unset - Generate
with,get,set, andunsetfor an optional struct field.