All Downloads are FREE. Search and download functionalities are using the official Maven repository.

it.auties.whatsapp.implementation.SocketRequest Maven / Gradle / Ivy

package it.auties.whatsapp.implementation;

import it.auties.whatsapp.exception.RequestException;
import it.auties.whatsapp.io.BinaryEncoder;
import it.auties.whatsapp.model.node.Node;
import it.auties.whatsapp.util.Exceptions;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;

import static java.util.concurrent.TimeUnit.SECONDS;

public record SocketRequest(String id, Object body, CompletableFuture future, Function filter) {
    private static final int TIMEOUT = 60;

    private SocketRequest(String id, Function filter, Object body) {
        this(id, body, futureOrTimeout(body), filter);
    }

    private static CompletableFuture futureOrTimeout(Object body) {
        var stacktraceProvider = Exceptions.current();
        return new CompletableFuture().orTimeout(TIMEOUT, SECONDS).exceptionally(throwable -> {
            var error = new RequestException("Node timed out: " + body);
            error.setStackTrace(stacktraceProvider.getStackTrace());
            error.addSuppressed(throwable);
            throw error;
        });
    }

    static SocketRequest of(Node body, Function filter) {
        return new SocketRequest(body.id(), filter, body);
    }

    static SocketRequest of(byte[] body) {
        return new SocketRequest(null, null, body);
    }

    byte[] toBytes() {
        return switch (body) {
            case byte[] bytes -> bytes;
            case Node node -> {
                try(var encoder = new BinaryEncoder()) {
                    yield encoder.encode(node);
                } catch (IOException exception) {
                    throw new UncheckedIOException(exception);
                }
            }
            case null, default -> throw new IllegalArgumentException("Cannot create request, illegal body: %s".formatted(body));
        };
    }

    public boolean complete(Node response, boolean exceptionally) {
        if (response == null) {
            future.complete(Node.of("error", Map.of("closed", true))); // Prevent NPEs all over the place
            return true;
        }

        if (exceptionally) {
            future.completeExceptionally(new RuntimeException("Cannot process request %s with %s".formatted(this, response)));
            return true;
        }

        if (filter != null && !filter.apply(response)) {
            return false;
        }

        future.complete(response);
        return true;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy