8000 Support nested tables · Issue #104 · tomitribe/crest · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Support nested tables #104
Open
Open
@rmannibucau

Description

@rmannibucau

Right now to support nested table we must either reimplement it or reuse TableInterceptor with some plumbing:

@Command
@ApplicationScoped
public class Commands {
    @Inject
    private JiraService jira;

    @Table(border = asciiSeparated)
    @Command(value = "list-projects")
    public List<FormattedProject> listProjects(@Option("jira-login") final JiraService.JiraLogin login,
                                                                       @Option("jira-client") final JiraService.JiraClient configuration) {
        final var formatter = new TableInterceptor();
        return jira.findProjectsWithTasks(login, configuration).stream()
                .map(p -> new FormattedProject(p.id(), p.label(), asTable(formatter, p.tasks())))
                .collect(toList());
    }

    @Table(border = asciiSeparated)
    private String asTable(final TableInterceptor formatter, final List<JiraService.Task> tasks) {
        final var formatted = formatter.intercept(new CrestContext() {
            @Override
            public Object proceed() {
                return tasks;
            }

            @Override
            public Method getMethod() {
                try {
                    return Commands.class.getDeclaredMethod("asTable", TableInterceptor.class, List.class);
                } catch (final NoSuchMethodException e) {
                    throw new IllegalStateException(e);
                }
            }

            @Override
            public List<Object> getParameters() {
                return List.of();
            }

            @Override
            public String getName() {
                return "formatAsTable";
            }

            @Override
            public List<ParameterMetadata> getParameterMetadata() {
                return List.of();
            }
        });
        if (formatted instanceof PrintOutput po) {
            final var out = new ByteArrayOutputStream();
            try (final var ps = new PrintStream(out)) {
                po.write(ps);
            } catch (final IOException e) {
                throw new IllegalStateException(e);
            }
            return out.toString(UTF_8);
        }
        throw new IllegalStateException("Unknown type: " + formatted);
    }

    public record FormattedProject(String id, String label, String tasks) {
    }
}

This works but I would expect asTable to be replacable by @Table on the nested type (public record Project(String id, String label, @Table(...config...) List<Task> tasks) { }) which would make it simpler but would also avoid to depend on the implementation module in commands.

Tip if you need the same feature: you can move this code in an utility class and call it to preformat your data before the rendering:

@Table(border = asciiSeparated)
@Command(value = "list-projects")
public List<FormattedProject> listProjects(....) {
    return jira.findProjects(login, configuration).stream()
            .map(p -> new FormattedProject(p.id(), p.label(), AsTable.asTable(p.tasks()))) // here is the trick, AsTable is previous code in a static utility class
            .collect(toList());
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0