doc_code_snippets! { mod "guide_05", type_ident=Guide05, template=r##" Here is an example of using a ConstValue struct to enable/disable access to a field (through an accessor method). This chapter demonstrates: -how to set fields on a ConstValue struct. -how to use a ConstValue struct in generic contexts. -how to use enable/disable methods based on the value of a ConstValue struct's field . //@use_codeblock:enum_decl,ignore Here we declare an enum describes whether a something is mutable or immutable. //@use_codeblock:const_struct_decl,ignore Here we have a ConstValue struct which describes the mutability of every field individually. //@use_codeblock:typealias,ignore These 2 type aliases use the SetField type alias, which allows setting a field of a type level struct.
In this case we are using the `All` accessor,which allows setting all fields of the struct with a value. //@use_codeblock:rect_decl,ignore Declares a rectangle which uses a ConstValue parameter to determine the mutability of each field. //@use_codeblock:constructor,ignore The constructor for Rectangle,taking in a ConstValue describing the mutability of each field. //@use_codeblock:set_mut,ignore The mutability method allows getting back the ConstFieldsMutability ConstValue-parameter .
FieldsMutabilityTrait ensures that `C` is a ConstFieldsMutability, and allows constructing it with the MTVAL associated constant(from MarkerType). The set_mutability method allows changing the mutability of the fields by passing in another ConstFieldsMutability.
In a later chapter we'll see a more concise way of changing the ConstValue-parameter. //@use_codeblock:getters,ignore Declares getters for every field. There are no constraints on the getter methods. //@use_codeblock:setter_0,ignore This is the setter method for the `x` field which requires that the same field on `C:FieldsMutabilityTrait` be `Mutable`. //@use_codeblock:setter_1,ignore These are the same as the setter for `x` but for other fields. //@use_codeblock:main_0,ignore This is a rectangle in which all setter methods are callable. The MTVAL associated constant is defined in the ::core_extensions::MarkerType trait, allowing any ConstValue to be instantiated. //@use_codeblock:main_1,ignore This is a rectangle in which only the setter methods for `w` and `h` are callable. The SetFields type alias allows setting multiple fields on a ConstValue struct.
The fields are located in the type_level::fields module, reexported here as fields_fm. //@use_codeblock:main_2,ignore This is a rectangle in which only the setter methods for `x` and `y` are callable. The CW associated constant, defined in ::type_level_values::const_wrapper::AsConstWrapper, wraps the type in a ConstWrapper.
ConstWrapper has multiple inherent methods that allow manipulating ConstValue structs, in this case using its `set_field_val` method.
ConstWrapper can also dereference to its wrapped type if it is a MarkerType, which all ConstValues are. //@use_codeblock:main_3,ignore This is an immutable rectangle. Note that like every other rectangles.all getters are still callable.




















# The entire thing //@use_codeblock:all,rust "##, code=r##" //@codeblock-start:all #[macro_use] extern crate derive_type_level; #[macro_use] extern crate type_level_values; use type_level_values::prelude::*; use type_level_values::field_traits::SetField; //@codeblock-start:enum_decl #[derive(TypeLevel)] #[typelevel( derive(ConstEq,ConstOrd), reexport(Variants), )] pub enum Mutability{ Mutable, Immutable, } //@codeblock-end:enum_decl //@codeblock-start:const_struct_decl #[derive(TypeLevel)] #[typelevel( derive(ConstEq,ConstOrd), //print_attributes, reexport(Struct,Traits), )] pub struct FieldsMutability{ pub x:Mutability, pub y:Mutability, pub w:Mutability, pub h:Mutability, } pub use self::type_level_FieldsMutability::fields as fields_fm; //@codeblock-end:const_struct_decl //@codeblock-start:typealias type AllMutable= SetField< FieldsMutability_Uninit ,fields_fm::All , Mutable> ; type AllImmutable= SetField< FieldsMutability_Uninit ,fields_fm::All , Immutable> ; //@codeblock-end:typealias mod rectangle{ use super::*; //@codeblock-start:rect_decl #[derive(MutConstValue)] #[mcv( derive(Default,Debug,Copy,Clone), Type="Rectangle",ConstValue="C", )] pub struct __Rectangle{ x:u32, y:u32, w:u32, h:u32, mutability:ConstWrapper } //@codeblock-end:rect_decl //@codeblock-start:constructor impl Rectangle{ pub fn new(x:u32,y:u32,w:u32,h:u32,_mutability:C)->Rectangle{ Rectangle{ x, y, w, h, mutability:ConstWrapper::NEW } } } //@codeblock-end:constructor //@codeblock-start:set_mut impl Rectangle{ pub fn mutability(&self)->C where C:FieldsMutabilityTrait { C::MTVAL } pub fn set_mutability(self,mutability:C)->Rectangle{ Rectangle{ x:self.x, y:self.y, w:self.w, h:self.h, mutability:ConstWrapper::NEW, } } } //@codeblock-end:set_mut //@codeblock-start:getters impl Rectangle{ pub fn x(&self) -> u32{ self.x } pub fn y(&self) -> u32{ self.y } pub fn w(&self) -> u32{ self.w } pub fn h(&self) -> u32{ self.h } } //@codeblock-end:getters //@codeblock-start:setter_0 impl Rectangle{ pub fn set_x(&mut self, x: u32) where EF: FieldsMutabilityTrait, { self.x = x; } } //@codeblock-end:setter_0 //@codeblock-start:setter_1 impl Rectangle{ pub fn set_y(&mut self, y: u32) where EF: FieldsMutabilityTrait, { self.y = y; } pub fn set_w(&mut self, w: u32) where EF: FieldsMutabilityTrait, { self.w = w; } pub fn set_h(&mut self, h: u32) where EF: FieldsMutabilityTrait, { self.h = h; } } //@codeblock-end:setter_1 } use rectangle::Rectangle; fn main(){ { //@codeblock-start:main_0 let mut rect=Rectangle::new(10,20,30,40,AllMutable::MTVAL); rect.set_x(100); rect.set_y(50); rect.set_w(25); rect.set_h(12); println!("{:?}", rect ); //@codeblock-end:main_0 } { //@codeblock-start:main_1 type XYMutable=SetFields; let mut rect=Rectangle::new(10,20,30,40,XYMutable::MTVAL); // this methods are disabled // rect.set_x(100); // rect.set_y(50); rect.set_w(25); rect.set_h(12); println!("{:?}", rect ); //@codeblock-end:main_1 } { //@codeblock-start:main_2 let mutability=AllMutable::CW .set_field_val( fields_fm::x , Mutable ) .set_field_val( fields_fm::y , Mutable ) .set_field_val( fields_fm::w , Immutable ) .set_field_val( fields_fm::h , Immutable ); let mut rect=Rectangle::new(10,20,30,40, *mutability ); rect.set_x(100); rect.set_y(50 ); // this methods are disabled // rect.set_w(25); // rect.set_h(12); println!("{:?}", rect ); //@codeblock-end:main_2 } { //@codeblock-start:main_3 let mut rect=Rectangle::new(10,20,30,40, AllImmutable::MTVAL ); // this methods are disabled // rect.set_x(100); // rect.set_y(50 ); // rect.set_w(25); // rect.set_h(12); println!("{:?}", rect ); //@codeblock-end:main_3 } } "##, }