#[derive(Optionable)]
{
// Attributes available to this derive:
#[optionable]
#[optionable_attr]
}
derive only.Expand description
Derive macro to derive the Optionable trait for structs/enums recursively by generating
a type with all fields recursively replaced with Option versions.
All non-required fields have to implement the Optionable trait. This trait is already implemented by this library
for many primitive types, wrapper and container types.
§Type-level attributes (on the struct/enum level)
optionable_attr: Helper for thederivetype-level attribute, for details see thederiveattribute.derive: Allows to specify derive attributes that should be attached to the generate optioned struct/enum. If you need to forward additional helper attributes to the generated type useattr_copyoroptionable_attrwith the attribute to forward as content (works for type and field attributes).ⓘ#[derive(optionable)] #[optionable(derive(Deserialize, Serialize))] #[optionable_attr(serde(rename_all = "camelCase"))] struct MyStruct{ #[optionable_attr(serde(rename = "firstName"))] name: String, surname: String, }attr_copy: Attributes that should be copied over the optioned type. If nokeyfilter is set all attributes with the given path are copied over.ⓘ#[derive(optionable)] #[optionable(derive(Deserialize, Serialize))] #[optionable(attr_copy(path=serde,key=rename))] struct MyStruct{ name: String, surname: String, }no_convert: Does not derive theOptionableConvertimplementation. Might be required if the target type involves smart pointers or unsized fields.ⓘ#[derive(optionable)] #[optionable(no_convert)] struct MyStruct{}option_wrap: Whether to wrap a field that is already anOption<T>inside an outerOption<Option<T>>for the optioned type. Useful for struct patching but not helpful once serializing to e.g. JSON is involved.ⓘ#[derive(optionable)] #[optionable(option_wrap)] struct MyStruct{}suffix: The name of the generated optioned struct/enum will be<original><suffix>with suffix defaulting to"Opt". The suffix value can be adjusted via e.g.#[optionable(suffix="Ac")].ⓘ#[derive(optionable)] #[optionable(suffix="Ac")] struct MyStruct{}
§Field-level attributes (for structs and struct-typed enum variants)
optionable_attr: Helper for thederivetype-level attribute, for details see thederiveattribute.required: The annotated field will be kept as is and won’t be transformed into some optional variant for the derived optioned Struct.ⓘ#[derive(optionable)] struct MyStruct{ street: String; // will be an `Option<String>` in the derived `MyStructOpt`. #[optionable(required)] number: u32; // will also be a u32 in the derived `MyStructOpt`. }optioned_type: For circumvention of the orphan rule. Uses the provided type for the optioned variant of the field. Ifno_convertis not set the provided type has to implementOptionedConvert<O>whereOis the type of this field in the original type.ⓘ#[derive(optionable)] struct MyStruct{ street: String; // will be an `Option<String>` in the derived `MyStructOpt`. #[optionable(optioned_type=MyInt)] number: i32; // will be a `MyInt` in the derived `MyStructOpt`. }merge: Customize the merge behaviour for the derivedOptionableConvert::mergeimplementation. The following values are supported (e.g. as#[merge(atomic)]):optionable_convertDefault behavior, just callOptionableConvert::mergefor the given field entry.atomicAlways override the field completly when present in the optioned type.append_not_presentKubernetessetmerge logic. Appends all entries that are not already present, requires for the field type toimpl Extend<T> + IntoIterator<Item=T> where T: PartialEq.iter_mapKubernetesmapmerge logic. Identifies if entries belong together via theoptionable::merge::OptionableMapKeysEqtrait. Merges entries that belong together (short-circuit, first match is merged) and appends all entries that are not already present, requires for the field type toimpl Extend<T> + IntoIterator<Item=T> where T: OptionableMapKeysEq + OptionableConvert.ignoreEntry is not merged but kept as is.
merge_map_key: Impliesrequired(see above). Furthermore, if at least one field has this attribute the traitOptionableMapKeysEqis implemented which uses the corresponding fields to determine if the “mapping keys” of two elements are equal. If the given struct isTthis becomes utilized if another struct has a field with themerge(map)attribute set and has a type thatimpl IntoIterator<Item=T>.ⓘ#[derive(optionable)] struct EnvVar{ #[merge_map_key] street: String; // will be a `String` in the derived `EnvVarOpt` and used as a merge key for the merge logic of `Container` below. value: String; // will be an `Option<String>` in the derived `EnvVarOpt`. } #[derive(optionable)] struct Container{ #[merge(iter_map)] env: Vec<EnvVar>; // will be a `Option<Vec<EnvVarOpt>>` in the derived `ContainerOpt`. The `OptionableConvert::merge` logic will merge entries that share the same keys (here the `name`) short-circuiting together and append those which did not find a merge target. }
§Kubernetes type-level attributes (on the struct/enum level)
Specialized Kubernetes specific type attributes to help deriving optioned types (in go called ApplyConfiguration)
for Kubernetes resources/subfields.
-
kube: Intended to be placed on types implementing subfields of a kube CRD spec. Copies over any#[(serde(rename="...")],#[(serde(rename_all="...")]and#[(serde(rename_all_fields="...")]attributes over to the optioned types.ⓘ#[optionable(kube())] #[derive(Optionable, Clone, Debug, Deserialize, Serialize, JsonSchema)] pub struct MyCrdSpecTemplate { pub replicas: u32, }If you need to configure optionable explicitly setting this is e.g. for a Struct equivalent to:
ⓘ#[optionable( attr_copy(path=serde,key=rename) attr_copy(path=serde,key=rename_all) attr_copy(path=serde,key=rename_all_fields) )] -
kube(resource): Very specialized version of thekube()attribute intended to be placed on the root element of akube::CustomResource. Besides forwarding the serde rename attribute likekube()it also adds the following behaviour:- Marks the
.metadatafield as required for the optioned type. - Derives
kube::core::Resourcefor the optioned type by referencing the original rootkube::CustomResource. - Adds specialized serde Serializing/Deserializing behaviour to the optioned type to handle the Group-Version-Kind envelope used by Kubernetes
(utilizing a
PhantomData-Marker on the optioned root type).
ⓘ#[derive(CustomResource)] #[kube( group = "example.localhost", version = "v1", kind = "CustomCrd", namespaced, derive = "Optionable", attr = "optionable(kube(resource),derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize))", )] - Marks the