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

Generic output redesign #46

Merged
merged 1 commit into from
Mar 18, 2024
Merged

Generic output redesign #46

merged 1 commit into from
Mar 18, 2024

Conversation

audunhalland
Copy link
Owner

@audunhalland audunhalland commented Mar 10, 2024

fixes #29

It's a major redesign of the responder/output-related traits.

It (currently) comes with the following caveat: (edit: this is fixed for one generics-level)

type MyResult<T> = Result<T, MyError>;

#[unimock]
trait MyTrait {
     // compile error:
     fn something(&self) -> MyResult<i32>;
     
     // must instead write:
     fn something<T>(&self) -> Result<i32, MyError>;
}

There exists a possible solution for this. Unimock selects a responder type based on the return signature. The new algorithm would select Generic<Result<Owned<i32>, Owned<i32>>> naively (for Result<i32, i32>. But that's just the semantics of the Generic responder: its inner types also need to implement Respond (so they can actually be nested, which is the whole point).

But there could also be a LeafGeneric responder. The structure -> SomethingGeneric<NonGenericType1, NonGenericType2> could select that instead. The semantics would be that the contained type is not interpreted as a responder, but as the direct response type.

Then the super-generic responder would only be chosen at the outer level in this scenario: -> SomethingGeneric<SomethingElseGeneric<NonGeneric>>.

status

This is now implemented and it works!

The "type hack" is also working. I've chosen some other names for the types, all of the output/responder code has been completely rewritten with a new fundamental architecture and foundational traits.

The core trait is output::Kind, a kind-of higher-kinded descriptor for output categories. The MockFn how has an OutputKind: Kind associated type.

Output kinds have to specify two associated types: Return and Respond types. The former is for storing a value in unimock and the latter is for responding through ApplyFn. The latter represents opt-out of Send + Sync.

Then there are the kinds themselves. The type-hack is about type kinds with generic parameters. A type signature with Option<T> has the Shallow kind, where the T itself is not a kind. A type signature with Option<Option<T>> has a Deep kind, applied in the following way: Deep<Option<Shallow<Option<T>>>>. So the innermost generic type has no restrictions on type aliasing (type MyResult<T> = Result<T, MyError>;), but the outermost has.

@audunhalland audunhalland changed the base branch from main to next March 10, 2024 15:49
@audunhalland audunhalland force-pushed the generic-responder branch 4 times, most recently from b5b34e9 to 150648c Compare March 17, 2024 14:22
@audunhalland audunhalland changed the title Generic responder Generic output redesign Mar 17, 2024
@audunhalland audunhalland force-pushed the generic-responder branch 4 times, most recently from e26e516 to e58460c Compare March 18, 2024 16:13
breaking change: Although the documentation is not exported, it's technically breaking
@audunhalland audunhalland merged commit 724a5ee into next Mar 18, 2024
4 checks passed
@audunhalland audunhalland deleted the generic-responder branch March 18, 2024 16:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant