From 03866db9b34b08a9808fc8f4ac87ba0de9cfec6f Mon Sep 17 00:00:00 2001 From: Yaroslav Bolyukin Date: Tue, 16 Aug 2022 12:18:25 +0000 Subject: [PATCH] doc(struct-versioning): explain semantics by example --- --- /dev/null +++ b/crates/struct-versioning/README.md @@ -0,0 +1,62 @@ +# struct-versioning + +The crate contains procedural macros for versioning data structures. +Macros [`versioned`] generate versioned variants of a struct. + +Example: +``` +# use struct_versioning::versioned; +#[versioned(version = 5, first_version = 2)] +struct Example {} + +// versioned macro will generate suffixed versions of example struct, +// starting from `Version{first_version or 1}` to `Version{version}` inclusive +let _ver2 = ExampleVersion2 {}; +let _ver3 = ExampleVersion3 {}; +let _ver4 = ExampleVersion4 {}; +let _ver5 = ExampleVersion5 {}; + +// last version will also be aliased with original struct name +let _orig: Example = ExampleVersion5 {}; + +#[versioned(version = 2, upper)] +#[derive(PartialEq, Debug)] +struct Upper { + #[version(..2)] + removed: u32, + #[version(2.., upper(10))] + added: u32, + + #[version(..2)] + retyped: u32, + #[version(2.., upper(retyped as u64))] + retyped: u64, +} + +// #[version] attribute on field allows to specify, in which versions of structs this field should present +// versions here works as standard rust ranges, start is inclusive, end is exclusive +let _up1 = UpperVersion1 {removed: 1, retyped: 0}; +let _up2 = UpperVersion2 {added: 1, retyped: 0}; + +// and upper() allows to specify, which value should be assigned to this field in `From` impl +assert_eq!( + UpperVersion2::from(UpperVersion1 {removed: 0, retyped: 6}), + UpperVersion2 {added: 10, retyped: 6}, +); +``` + +In this case, the upgrade is described in `on_runtime_upgrade` using the `translate_values` substrate feature + +```ignore +#[pallet::hooks] +impl Hooks> for Pallet { + fn on_runtime_upgrade() -> Weight { + if StorageVersion::get::>() < StorageVersion::new(1) { + >::translate_values::(|v| { + Some(::from(v)) + }) + } + 0 + } +} +``` --- a/crates/struct-versioning/src/lib.rs +++ b/crates/struct-versioning/src/lib.rs @@ -14,42 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Unique Network. If not, see . -//! struct-versioning -//! The crate contains procedural macros for versioning data structures. -//! Macros `versioned` generate versioned variants of a struct. -//! -//! Example: -//! #[struct_versioning::versioned(version = 2, upper)] -//! ... -//! pub struct ItemData { -//! pub const_data: BoundedVec, -//! -//! #[version(..2)] -//! pub variable_data: BoundedVec, -//! } -//! ... -//! `#[version(..2)]` that means that any version before 2 will be upgraded to 2 via the `upper` function. -//! When version become 3 `#[struct_versioning::versioned(version = 3, upper)]` this field will be removed. -//! *upper* - generate From impls, which converts old version of structs to new -//! In this case, the upgrade is described in `on_runtime_upgrade` using the `translate_values` substrate feature -//! -//! #[pallet::hooks] -//! impl Hooks> for Pallet { -//! fn on_runtime_upgrade() -> Weight { -//! if StorageVersion::get::>() < StorageVersion::new(1) { -//! >::translate_values::(|v| { -//! Some(::from(v)) -//! }) -//! } -//! 0 -//! } -//! } -//! -//! Another functionality -/// -/// `#[versioned(version = 1[, first_version = 1][, upper][, versions])]` -/// - *first_version* - allows to skip generation of structs, which predates first supported version -/// - *versions* - generate enum, which contains all possible versions of struct +#![doc = include_str!("../README.md")] + use proc_macro::TokenStream; use quote::format_ident; use syn::{ -- gitstuff