Crates.io | oxinat_derive |
lib.rs | oxinat_derive |
version | 0.8.0 |
source | src |
created_at | 2024-05-24 16:43:07.687714 |
updated_at | 2024-06-07 19:43:09.502798 |
description | oxinat xapi-oxidized procedural macros |
homepage | |
repository | https://github.com/WilkinsonK/xapi-oxidized |
max_upload_size | |
id | 1251322 |
size | 37,314 |
This crate defines the magic behind the URI build mappings found in
oxinate_core
and the root crate, oxinat
. Primarily this crate is
used in the core library to generate relevant methods that eventually
result in the URI building system in oxinat
.
At this time, the derive macros do not support unit structs at the top-level of structural definitions, but does support for regular structs and enumerations.
use oxinat_derive::UriBuilder;
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "some/uri")]
#[match_path(path = "some/uri/{some_parameter}")]
struct SomeUriBuilder {
#[param]
some_parameter: Option<String>
}
As briefly described above, there are several attribute modifiers used
to more deeply define how, at build-time, a URI may be constructed.
It is important to know that match arms are constructed in order of
each #[match_path]
declaration.
The first, and most important directive, will be the #[match_path]
macro. This tells oxinat_derive
how to construct build the resulting
build
method that will be defined at compile time. It comes with two
attributes, path
and requires
(optional).
path
is required. This allows oxinat_derive
to know what and how
pattern(s) should be constructed for the builder.requires
is an optional attribute. It accepts a string of some
boolean expression (e.g. "2+2 == 4"
). This modifies the match
arm to only be valid on the condition. NOTE: At this scope, the
attribute will match at the 'self' level of the builder.Both #[parent]
and #[param]
behave effectively the same way when
constructing match arms for the eventual build
method. However,
there are differences when constructing certain methods that allow for
pre-build customization.
All-in-all, it will look the same on the surface. Before URI construction, methods will be implemented for these fields which allow a user to set the inner values.
For example:
use oxinat_derive::UriBuilder;
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/some/uri")]
#[match_path(path = "{parent}/some/uri/{some_parameter}")]
struct SomeUriBuilder {
#[param]
some_parameter: Option<String>
#[parent]
parent: Option<String>
}
// Under the hood, these methods will be implemented.
impl SomeUriBuilder {
pub fn with_some_parameter(mut self, value: String) -> Self {
...
}
pub fn with_parent(mut self, value: String) -> Self {
...
}
}
In addition to generating methods, declaring fields as either a parent or a param allows for some customization with additional attributes.
requires
works similar to how it behaves at the #[match_path]
level, but instead at the parameter level.map_from
allows for specific formatting/manipulation of a value
during build-time of the URI.Both of these directives behave the same as
#[match_path(requires = "..")]
. This means that it will accept a
stringed boolean expression, such as a closure, function or macro.