#pragma once
#if ENABLE(FETCH_API)
#include "DOMFormData.h"
#include "FetchBodyConsumer.h"
#include "FormData.h"
#include "JSDOMPromiseDeferred.h"
#include "URLSearchParams.h"
#include <wtf/Variant.h>
namespace WebCore {
class FetchBodyOwner;
class FetchResponseSource;
class ScriptExecutionContext;
class FetchBody {
public:
void arrayBuffer(FetchBodyOwner&, Ref<DeferredPromise>&&);
void blob(FetchBodyOwner&, Ref<DeferredPromise>&&, const String&);
void json(FetchBodyOwner&, Ref<DeferredPromise>&&);
void text(FetchBodyOwner&, Ref<DeferredPromise>&&);
void formData(FetchBodyOwner&, Ref<DeferredPromise>&& promise) { promise.get().reject(0); }
#if ENABLE(STREAMS_API)
void consumeAsStream(FetchBodyOwner&, FetchResponseSource&);
#endif
bool isBlob() const { return WTF::holds_alternative<Ref<const Blob>>(m_data); }
bool isFormData() const { return WTF::holds_alternative<Ref<FormData>>(m_data); }
bool isArrayBuffer() const { return WTF::holds_alternative<Ref<const ArrayBuffer>>(m_data); }
bool isArrayBufferView() const { return WTF::holds_alternative<Ref<const ArrayBufferView>>(m_data); }
bool isURLSearchParams() const { return WTF::holds_alternative<Ref<const URLSearchParams>>(m_data); }
bool isText() const { return WTF::holds_alternative<String>(m_data); }
bool isReadableStream() const { return m_isReadableStream; }
using BindingDataType = Variant<RefPtr<Blob>, RefPtr<ArrayBufferView>, RefPtr<ArrayBuffer>, RefPtr<DOMFormData>, RefPtr<URLSearchParams>, String>;
static FetchBody extract(ScriptExecutionContext&, BindingDataType&&, String&);
static FetchBody loadingBody() { return { }; }
static FetchBody readableStreamBody();
void loadingFailed();
void loadingSucceeded();
RefPtr<FormData> bodyForInternalRequest(ScriptExecutionContext&) const;
FetchBodyConsumer& consumer() { return m_consumer; }
void consumeOnceLoadingFinished(FetchBodyConsumer::Type, Ref<DeferredPromise>&&, const String&);
void cleanConsumePromise() { m_consumePromise = nullptr; }
FetchBody clone() const;
private:
explicit FetchBody(Ref<const Blob>&& data) : m_data(WTFMove(data)) { }
explicit FetchBody(Ref<const ArrayBuffer>&& data) : m_data(WTFMove(data)) { }
explicit FetchBody(Ref<const ArrayBufferView>&& data) : m_data(WTFMove(data)) { }
explicit FetchBody(Ref<FormData>&& data) : m_data(WTFMove(data)) { }
explicit FetchBody(String&& data) : m_data(WTFMove(data)) { }
explicit FetchBody(Ref<const URLSearchParams>&& data) : m_data(WTFMove(data)) { }
explicit FetchBody(const FetchBodyConsumer& consumer) : m_consumer(consumer) { }
FetchBody() = default;
void consume(FetchBodyOwner&, Ref<DeferredPromise>&&);
void consumeArrayBuffer(Ref<DeferredPromise>&&);
void consumeArrayBufferView(Ref<DeferredPromise>&&);
void consumeText(Ref<DeferredPromise>&&, const String&);
void consumeBlob(FetchBodyOwner&, Ref<DeferredPromise>&&);
const Blob& blobBody() const { return WTF::get<Ref<const Blob>>(m_data).get(); }
FormData& formDataBody() { return WTF::get<Ref<FormData>>(m_data).get(); }
const FormData& formDataBody() const { return WTF::get<Ref<FormData>>(m_data).get(); }
const ArrayBuffer& arrayBufferBody() const { return WTF::get<Ref<const ArrayBuffer>>(m_data).get(); }
const ArrayBufferView& arrayBufferViewBody() const { return WTF::get<Ref<const ArrayBufferView>>(m_data).get(); }
String& textBody() { return WTF::get<String>(m_data); }
const String& textBody() const { return WTF::get<String>(m_data); }
const URLSearchParams& urlSearchParamsBody() const { return WTF::get<Ref<const URLSearchParams>>(m_data).get(); }
using Data = Variant<std::nullptr_t, Ref<const Blob>, Ref<FormData>, Ref<const ArrayBuffer>, Ref<const ArrayBufferView>, Ref<const URLSearchParams>, String>;
Data m_data { nullptr };
FetchBodyConsumer m_consumer { FetchBodyConsumer::Type::None };
RefPtr<DeferredPromise> m_consumePromise;
bool m_isReadableStream { false };
};
}
#endif // ENABLE(FETCH_API)