Attribute macro for implementing methods on both Foo and ArchivedFoo.

Overview

rkyv_impl

Crates.io Docs.rs

Implement methods for Foo and ArchivedFoo in a single impl block.

use rkyv::Archive;
use rkyv_impl::*;
use std::iter::Sum;

#[derive(Archive)]
struct Foo<T> {
    elements: Vec<T>
}

#[archive_impl(transform_bounds(T))]
impl<T> Foo<T> {
    #[archive_method(transform_bounds(T))]
    fn sum<S>(&self) -> S
    where
        T: Clone,
        S: Sum<T>
    {
        self.elements.iter().cloned().sum()
    }
}

// Notice that the trait bounds are transformed so that
// `T` is replaced with `T::Archived`.
fn call_generated_method<T, S>(foo: &ArchivedFoo<T>)
where
    T: Archive,
    T::Archived: Clone,
    S: Sum<T::Archived>
{
    let _ = foo.sum::<S>();
}

License: MIT/Apache-2.0

Comments
  • Explicit `T: Archive` bounds

    Explicit `T: Archive` bounds

    Right now, the user must provide T: Archive bounds for generics, but this unnecessarily constrains the non-archived impl, for example:

    #[archive_impl]
    impl<T> Foo<T>
    where
        T: Archive<Archived = T>,
    {
        fn get_slice(&self) -> &[T] {
            &self.field
        }
    }
    

    This leaves the bound on T within the impl<T> Foo<T> ... { ... } item, but the bound is really only required for the impl<T> ArchivedFoo<T> item.

    We should find a way to limit the placement of these bounds, either with another macro annotations or by placing them automatically. But automatic placement may go too far in the opposite direction; we don't always need T: Archive bounds, for example:

    struct Foo<T> {
        marker: PhantomData<T>
    }
    
    opened by bonsairobo 3
  • Make inheritance of original `impl` and method trait bounds opt-in

    Make inheritance of original `impl` and method trait bounds opt-in

    When trait bounds are always inherited, this may over-constrain the generated methods, causing superfluous bounds to propagate through all generic code.

    We could have an opt-in syntax like:

    #[archive_impl(inherit, bounds(...))]
    impl<T> Foo<T> {
        #[archive_method(inherit, bounds(...))]
        fn method(...) { ... }
    }
    
    opened by bonsairobo 2
  • "Conditional compilation" blocks

    Sometimes you get into tricky situations where you just need to specialize the archived implementation of a method. We might be able to support something like:

    #[archive_impl]
    impl Foo {
        fn do_it_up(&self) {
            #[if_archived] {
                // some archived-specific logic, like deserializing
            } #[else] {
                // the alternative
            }
        }
    }
    

    I don't know if that's good syntax. We might need to experiment.

    opened by bonsairobo 1
  • Generalizing to generic traits

    Generalizing to generic traits

    The motivating use case for this issue is:

    #[archive_impl(Foo)]
    impl From<&Foo> for Bar { ... }
    

    So in this case, Foo: Archived and we want to generate the equivalent impl From<&ArchivedFoo> for Bar { ... }

    opened by bonsairobo 0
  • Original-only bounds

    Original-only bounds

    I haven't thought of a convincing use case for omitting bounds from the original impl or fn items, but I suspect such a use case exists. Implementing this feature would not be very challenging, so this could be a good first issue for new contributors. I will leave open until I encounter the need for this.

    opened by bonsairobo 5
  • Supporting other `Self` types

    Supporting other `Self` types

    There are several variants of syn::Type that we ignore in the macro, and some of these might actually have valid use cases:

            /// A raw pointer type: `*const T` or `*mut T`.
            Ptr(TypePtr),
    
            /// A reference type: `&'a T` or `&'a mut T`.
            Reference(TypeReference),
    
            /// A dynamically sized slice type: `[T]`.
            Slice(TypeSlice),
    
            /// A trait object type `dyn Bound1 + Bound2 + Bound3` where `Bound` is a
            /// trait or a lifetime.
            TraitObject(TypeTraitObject),
    
            /// A tuple type: `(A, B, C, String)`.
            Tuple(TypeTuple),
    
    opened by bonsairobo 0
Owner
Duncan
Duncan
Advent of Code 2015, done entirely in Rust both for the challenge and as a way to learn

Advent of Code 2015 In preparation for Advent of Code 2021, I wanted to go back and try some of the older challenges. I figured it made the most sense

Matt 1 Dec 9, 2021
The most primitive and the fastest implementation of a fixed-size last-in-first-out stack on stack in Rust, for Copy-implementing types

This is the simplest and the fastest (faster than Vec!) implementation of a last-in-first-out stack data structure, on stack, when stack elements are

Yegor Bugayenko 10 Jun 18, 2023
A copypastable guide to implementing simple derive macros in Rust.

A copypastable guide to implementing simple derive macros in Rust. The goal Let's say we have a trait with a getter trait MyTrait {

Imbolc 131 Dec 27, 2022
Might have a go at implementing Pulumi for Rust 🤷‍♂️

Might have a go at implementing Pulumi for Rust ??‍♂️

Nick 11 Nov 1, 2022
Inverse kinematics plugin for Bevy implementing the FABRIK algorithm.

Inverse kinematics plugin for Bevy implementing the FABRIK algorithm.

Georg Friedrich Schuppe 11 Dec 31, 2022
A Rust proc-macro crate which derives functions to compile and parse back enums and structs to and from a bytecode representation

Bytecode A simple way to derive bytecode for you Enums and Structs. What is this This is a crate that provides a proc macro which will derive bytecode

null 4 Sep 3, 2022
A stupid macro that compiles and executes Rust and spits the output directly into your Rust code

inline-rust This is a stupid macro inspired by inline-python that compiles and executes Rust and spits the output directly into your Rust code. There

William 19 Nov 29, 2022
This crate provides a convenient macro that allows you to generate type wrappers that promise to always uphold arbitrary invariants that you specified.

prae This crate provides a convenient macro that allows you to generate type wrappers that promise to always uphold arbitrary invariants that you spec

null 96 Dec 4, 2022
The nightly_crimes!{} macro commits horrible crimes to allow you to enable nightly features on the stable compiler.

The nightly_crimes!{} macro commits horrible crimes to allow you to enable nightly features on the stable compiler.

Mara Bos 151 Dec 16, 2022
This crate defines a single macro that is a brainfunct compile-time interpreter.

Compile Protection This crate defines a single macro that is a brainfunct compile-time interpreter. One example is as follows #![recursion_limit = "18

John Marsden 7 Nov 29, 2021
Example of structuring a proc macro crate for testability

testing-proc-macros Example of structuring a proc macro crate for testability. See accompanying blog post for details. License Licensed under either o

Ferrous Systems 12 Dec 11, 2022
Macros to make writing proc-macro crates easy

proc-easy Macros to make writing proc-macro crates easy. This crate provides mainly macros and supporting types and traits to reduce amount of boilerp

Zakarum 7 Jan 1, 2023
Rust macro to use a match-like syntax as a elegant alternative to nesting if-else statement

cond Rust macro to use a match-like syntax as an elegant alternative to many if-else statements. I got the idea from empty Go switch statements. I tho

CheckM4te 3 Nov 23, 2023
A library and tool for automata and formal languages, inspired by JFLAP

Sugarcubes is a library and application for automata and formal languages. It is inspired by JFLAP, and is intended to eventually to be an alternative to JFLAP.

Henry Sloan 22 Nov 2, 2022
This is a Discord bot written in Rust to translate to and from the Bottom Encoding Standard using bottom-rs and Serenity.

bottom-bot This is a Discord bot written in Rust to translate to and from the Bottom Encoding Standard using bottom-rs and Serenity. Ever had this pro

Bottom Software Foundation 11 Dec 10, 2022
An implementation of Code Generation and Factoring for Fast Evaluation of Low-order Spherical Harmonic Products and Squares

sh_product An implementation of Code Generation and Factoring for Fast Evaluation of Low-order Spherical Harmonic Products and Squares (paper by John

Simon Brown 7 Dec 2, 2022
lightweight and customizable rust s-expression (s-expr) parser and printer

s-expr Rust library for S-expression like parsing and printing parser keeps track of spans, and representation (e.g. number base) number and decimal d

Vincent Hanquez 5 Oct 26, 2022
Crates Registry is a tool for serving and publishing crates and serving rustup installation in offline networks.

Crates Registry Description Crates Registry is a tool for serving and publishing crates and serving rustup installation in offline networks. (like Ver

TalYRoni 5 Jul 6, 2023
Simplify temporary email management and interaction, including message retrieval and attachment downloads, using Rust.

Tempmail The Tempmail simplifies temporary email management and interaction, including message retrieval and attachment downloads, using the Rust prog

Dilshad 6 Sep 21, 2023