Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lattice specialization could allow methods to be removed from macro #1

Closed
withoutboats opened this Issue Sep 19, 2016 · 3 comments

Comments

Projects
None yet
1 participant
@withoutboats
Copy link
Collaborator

withoutboats commented Sep 19, 2016

The current syntax of the routes! macro requires the author to specify every method each resource supports, e.g.:

routes! {
     resource Photo => ["get", "index", "put"] { ... }
}

The user then additionally provides an impl of the trait associated with each method for Photo.

This is redundant work, but its necessary for the macro to be expanded in a way which attaches each method for that resource (see the methods! macro in the current version of the source).

With lattice specialization, we could instead provide a single entry point, specialized for all of the combinations of methods that could be supported. This would be a lot of boilerplate for cargonauts, but it would save much more boilerplate for cargonauts users. For example:

struct<R: router::Router> Router<R> {
    // underlying method specific functions
    fn attach_get<T: Get>(&mut self) { ... }
    fn attach_index<T: Index>(&mut self) { ... }

    // specialized entry point method
    default fn attach_methods<T>(&mut self) {
        // base case is null - you have defined no methods for this resource
    }
    default fn attach_methods<T: Get>(&mut self) {
        self.attach_get::<T>();
    }
    default fn attach_methods<T: Index>(&mut self) {
        self.attach_index::<T>();
    }
    fn attach_methods<T: Get + Index>(&mut self) {
        self.attach_get::<T>();
        self.attach_index::<T>();
    }
}

This requires lattice specialization because the method traits do not form a specialization order between them.

@withoutboats

This comment has been minimized.

Copy link
Collaborator Author

withoutboats commented Nov 22, 2016

Writing so I will remember it when I can implement this:

This does not require lattice specialization! It just requires further use of the MaybeTrait pattern. For example:

trait MaybeGet {
    fn attach_get<R: Router>(router: &mut R);
}

// By default, attach nothing
impl<T> MaybeGet for T {
    default fn attach_get<R: Router>(_: &mut R) { }
}

impl<T: Get> MaybeGet for T {
    fn attach_get<R: Router>(router: &mut R) {
        router.attach_get(...)
    }
}
@withoutboats

This comment has been minimized.

Copy link
Collaborator Author

withoutboats commented Nov 22, 2016

Implemented this for resource methods, relation methods in the next day or two, then I'll close this issue 🎉.

@withoutboats

This comment has been minimized.

Copy link
Collaborator Author

withoutboats commented Nov 23, 2016

Now implemented

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.