doc(versionable): improve proc macro doc with an example

This commit is contained in:
Nicolas Sarlin
2024-10-16 16:24:06 +02:00
committed by Nicolas Sarlin
parent 1406924235
commit 075e87495d
3 changed files with 48 additions and 5 deletions

View File

@@ -12,7 +12,7 @@ use crate::{
};
/// Generates an impl block for the From trait. This will be:
/// ```
/// ```ignore
/// impl From<Src> for Dest {
/// fn from(value: Src) -> Self {
/// ...[constructor]...
@@ -39,7 +39,7 @@ pub(crate) fn generate_from_trait_impl(
}
/// Generates an impl block for the TryFrom trait. This will be:
/// ```
/// ```ignore
/// impl TryFrom<Src> for Dest {
/// type Error = ErrorType;
/// fn from(value: Src) -> Self {

View File

@@ -131,6 +131,49 @@ pub fn derive_versions_dispatch(input: TokenStream) -> TokenStream {
///
/// This macro has a mandatory attribute parameter, which is the name of the versioned enum for this
/// type. This enum can be anywhere in the code but should be in scope.
///
/// Example:
/// ```ignore
/// // The structure that should be versioned, as defined in your code
/// #[derive(Versionize)]
/// // We have to link to the enum type that will holds all the versions of this
/// // type. This can also be written `#[versionize(dispatch = MyStructVersions)]`.
/// #[versionize(MyStructVersions)]
/// struct MyStruct<T> {
/// attr: T,
/// builtin: u32,
/// }
///
/// // To avoid polluting your code, the old versions can be defined in another module/file, along with
/// // the dispatch enum
/// #[derive(Version)] // Used to mark an old version of the type
/// struct MyStructV0 {
/// builtin: u32,
/// }
///
/// // The Upgrade trait tells how to go from the first version to the last. During unversioning, the
/// // upgrade method will be called on the deserialized value enough times to go to the last variant.
/// impl<T: Default> Upgrade<MyStruct<T>> for MyStructV0 {
/// type Error = Infallible;
///
/// fn upgrade(self) -> Result<MyStruct<T>, Self::Error> {
/// Ok(MyStruct {
/// attr: T::default(),
/// builtin: self.builtin,
/// })
/// }
/// }
///
/// // This is the dispatch enum, that holds one variant for each version of your type.
/// #[derive(VersionsDispatch)]
/// // This enum is not directly used but serves as a template to generate a new enum that will be
/// // serialized. This allows recursive versioning.
/// #[allow(unused)]
/// enum MyStructVersions<T> {
/// V0(MyStructV0),
/// V1(MyStruct<T>),
/// }
/// ```
#[proc_macro_derive(Versionize, attributes(versionize))]
pub fn derive_versionize(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);

View File

@@ -48,10 +48,10 @@ pub trait VersionizeOwned {
fn versionize_owned(self) -> Self::VersionedOwned;
}
/// This trait is used as a proxy to be more flexible when deriving Versionize for Vec<T>.
/// This trait is used as a proxy to be more flexible when deriving Versionize for `Vec<T>`.
///
/// This way, we can chose to skip versioning Vec<T> if T is a native types but still versionize in
/// a loop if T is a custom type.
/// This way, we can chose to skip versioning `Vec<T>` if T is a native types but still versionize
/// in a loop if T is a custom type.
/// This is used as a workaround for feature(specialization) and to bypass the orphan rule.
pub trait VersionizeSlice: Sized {
type VersionedSlice<'vers>: Serialize