root/headers/private/netservices2/HttpFields.h
/*
 * Copyright 2022 Haiku Inc. All rights reserved.
 * Distributed under the terms of the MIT License.
 */

#ifndef _B_HTTP_FIELDS_H_
#define _B_HTTP_FIELDS_H_

#include <list>
#include <optional>
#include <string_view>
#include <variant>
#include <vector>

#include <ErrorsExt.h>
#include <String.h>


namespace BPrivate {

namespace Network {


class BHttpFields
{
public:
                // Exceptions
        class InvalidInput;

        // Wrapper Types
        class FieldName;
        class Field;

        // Type Aliases
        using ConstIterator = std::list<Field>::const_iterator;

        // Constructors & Destructor
                                                                BHttpFields();
                                                                BHttpFields(std::initializer_list<Field> fields);
                                                                BHttpFields(const BHttpFields& other);
                                                                BHttpFields(BHttpFields&& other);
                                                                ~BHttpFields() noexcept;

        // Assignment operators
                        BHttpFields&            operator=(const BHttpFields&);
                        BHttpFields&            operator=(BHttpFields&&) noexcept;

        // Access list
                        const Field&            operator[](size_t index) const;

        // Modifiers
                        void                            AddField(const std::string_view& name,
                                                                        const std::string_view& value);
                        void                            AddField(BString& field);
                        void                            AddFields(std::initializer_list<Field> fields);
                        void                            RemoveField(const std::string_view& name) noexcept;
                        void                            RemoveField(ConstIterator it) noexcept;
                        void                            MakeEmpty() noexcept;

        // Querying
                        ConstIterator           FindField(const std::string_view& name) const noexcept;
                        size_t                          CountFields() const noexcept;
                        size_t                          CountFields(const std::string_view& name) const noexcept;

        // Range-based iteration
                        ConstIterator           begin() const noexcept;
                        ConstIterator           end() const noexcept;

private:
                        std::list<Field>        fFields;
};


class BHttpFields::InvalidInput : public BError
{
public:
                                                                InvalidInput(const char* origin, BString input);

        virtual const char*                     Message() const noexcept override;
        virtual BString                         DebugMessage() const override;

                        BString                         input;
};


class BHttpFields::FieldName
{
public:
        // Comparison
                        bool                            operator==(const BString& other) const noexcept;
                        bool                            operator==(const std::string_view& other) const noexcept;
                        bool                            operator==(const FieldName& other) const noexcept;

        // Conversion
        operator                                        std::string_view() const;

private:
        friend class BHttpFields;

                                                                FieldName() noexcept;
                                                                FieldName(const std::string_view& name) noexcept;
                                                                FieldName(const FieldName& other) noexcept;
                                                                FieldName(FieldName&&) noexcept;
                        FieldName&                      operator=(const FieldName& other) noexcept;
                        FieldName&                      operator=(FieldName&&) noexcept;

                        std::string_view        fName;
};


class BHttpFields::Field
{
public:
        // Constructors
                                                                Field() noexcept;
                                                                Field(const std::string_view& name, const std::string_view& value);
                                                                Field(BString& field);
                                                                Field(const Field& other);
                                                                Field(Field&&) noexcept;

        // Assignment
                        Field&                          operator=(const Field& other);
                        Field&                          operator=(Field&& other) noexcept;

        // Access Operators
                        const FieldName&        Name() const noexcept;
                        std::string_view        Value() const noexcept;
                        std::string_view        RawField() const noexcept;
                        bool                            IsEmpty() const noexcept;

private:
        friend class BHttpFields;

                                                                Field(BString&& rawField);

                        std::optional<BString> fRawField;

                        FieldName                       fName;
                        std::string_view        fValue;
};


} // namespace Network

} // namespace BPrivate

#endif // _B_HTTP_FIELDS_H_