From b4452f176d2dcf468b35df5ef6da9852f0a9a540 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 17 Apr 2022 21:09:07 +0100 Subject: [PATCH] serde_with_compat: Add some docs, since this is confusing Signed-off-by: Ian Jackson --- src/utils.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/utils.rs b/src/utils.rs index 88b03176..c04918b1 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -406,6 +406,32 @@ macro_rules! want_let { }; } +/// Allows the use of serde for a compat struct +/// +/// Ideally we would have +/// ```rust ignore +/// #[derive(Deserialize)] +/// #[serde(try_from=Compat)] +/// struct Main { /* new definition */ } +/// +/// #[derive(Deserialize)] +/// #[serde(untagged)] +/// enum Compat { V1(Main), V2(Old) } +/// +/// #[derive(Deserialize)] +/// struct Old { /* old version we still want to read */ } +/// +/// impl TryFrom for Main { /* ... */ } +/// ``` +/// +/// But the impl for `Compat` ends up honouring the `try_from` on `Main` +/// so is recursive. We solve that abusing serde's remote feature. +/// +/// For an example, see `IOccultIlk`. +/// +/// The name of the main structure must be passed twice, once as an +/// identifier and once as a literal, because `stringify!` doesn't work +/// in the serde attribute. #[macro_export] macro_rules! serde_with_compat { { [ #[ $($attrs:meta)* ] ] [ $vis:vis ] [ $($intro:tt)* ] -- 2.30.2