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

Support generic types as input and output types #35

Closed
roookeee opened this issue Jun 11, 2020 · 5 comments
Closed

Support generic types as input and output types #35

roookeee opened this issue Jun 11, 2020 · 5 comments
Assignees
Labels
bug Something isn't working enhancement New feature or request resolved in develop semver-minor

Comments

@roookeee
Copy link
Owner

roookeee commented Jun 11, 2020

Currently the Datus class expects two Class<T> parameters to infer the input and output types. These cannot be passed if e.g. T is a List<T> as List<T>.class cannot be created / obtained.

We should add an overload to Datus.forTypes() without any parameters that leaves the type definition to the caller via Datus.<List<Integer>, List<String>>forTypes() (it is ugly indeed, but it works, don't think there is a better way).

Thanks to #33 for noticing this issue ! :)

@roookeee roookeee self-assigned this Jun 11, 2020
@roookeee roookeee added bug Something isn't working enhancement New feature or request semver-minor labels Jun 11, 2020
@roookeee
Copy link
Owner Author

Working test case:

package com.github.roookeee.datus.generics;

import com.github.roookeee.datus.api.Datus;
import com.github.roookeee.datus.api.Mapper;
import com.github.roookeee.datus.immutable.ConstructorParameter;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class GenericsTest {

    @Test
    public void shouldSupportGenericTypesInTheImmutableApi() {
        //given
        ImmutableContainer<Integer> input = new ImmutableContainer<>(5);
        Mapper<ImmutableContainer<Integer>, ImmutableContainer<String>> mapper =
                Datus.<ImmutableContainer<Integer>, ImmutableContainer<String>>forTypes()
                // type inference hates us a little here, the generic type of immutable is inferred by the passed lambda
                // which is generic and thus object -> have to specify type although it is a bit ugly
                .<String>immutable(ImmutableContainer::new)
                .from(ImmutableContainer::getElement).map(Object::toString).to(ConstructorParameter::bind)
                .build();

        //when
        ImmutableContainer<String> result = mapper.convert(input);

        //then
        assertThat(result.getElement()).isEqualTo(result.getElement());
    }

    @Test
    public void shouldSupportGenericTypesInTheMutableApi() {
        //given
        MutableContainer<Integer> input = new MutableContainer<>();
        input.setElement(5);
        Mapper<MutableContainer<Integer>, MutableContainer<String>> mapper =
                Datus.<MutableContainer<Integer>, MutableContainer<String>>forTypes()
                        .mutable(MutableContainer::new)
                        .from(MutableContainer::getElement).map(Object::toString).into(MutableContainer::setElement)
                        .build();

        //when
        MutableContainer<String> result = mapper.convert(input);

        //then
        assertThat(result.getElement()).isEqualTo(result.getElement());
    }

    private static class ImmutableContainer<T> {
        private final T element;

        public ImmutableContainer(T element) {
            this.element = element;
        }

        public T getElement() {
            return element;
        }
    }

    private static class MutableContainer<T> {
        private T element;

        public T getElement() {
            return element;
        }

        public void setElement(T element) {
            this.element = element;
        }
    }
}

@roookeee
Copy link
Owner Author

roookeee commented Jun 11, 2020

Initial implementation in branch issue-35 @ 7638730

Will do some doc and finish this sometime today or tomorrow

@roookeee
Copy link
Owner Author

roookeee commented Jun 13, 2020

Thorough tests & documentation are done, letting it sit for a while in case I think of some weird edge-case that needs to be handled / fixed. Will release 1.4.1 or even 1.5.0 this month though.

@roookeee
Copy link
Owner Author

roookeee commented Jun 14, 2020

Merged into develop (see commit above this comment) - leaving this open until I have released a new datus version.

@roookeee roookeee changed the title Support generic container types Support generic types Jun 19, 2020
@roookeee roookeee changed the title Support generic types Support generic types as input and output types Jun 19, 2020
@roookeee
Copy link
Owner Author

Datus 1.5.0 released

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request resolved in develop semver-minor
Projects
None yet
Development

No branches or pull requests

1 participant