folly/folly/json/DynamicParser-inl.h

/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <type_traits>

#include <boost/function_types/parameter_types.hpp>
#include <boost/mpl/equal.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/vector.hpp>

#include <folly/Conv.h>
#include <folly/Traits.h>

namespace folly {

// Auto-conversion of key/value based on callback signature, documented in
// DynamicParser.h.
namespace detail {
class IdentifyCallable {};

template <IdentifyCallable::Kind, typename Fn>
struct ArgumentTypesByKind {};
ArgumentTypesByKind<IdentifyCallable::Kind::MemberFunction, Fn>;
ArgumentTypesByKind<IdentifyCallable::Kind::Function, Fn>;

ArgumentTypes;

// At present, works for lambdas or plain old functions, but can be
// extended.  The comparison deliberately strips cv-qualifiers and
// reference, leaving that choice up to the caller.
template <typename Fn, typename... Args>
struct HasArgumentTypes
    : boost::mpl::template equal<
          typename boost::mpl::
              transform<ArgumentTypes<Fn>, remove_cvref<boost::mpl::_1>>::type,
          boost::mpl::vector<Args...>>::type {};
EnableForArgTypes;

// No arguments
template <typename Fn>
EnableForArgTypes<Fn> invokeForKeyValue(
    Fn f, const folly::dynamic&, const folly::dynamic&) {}

// 1 argument -- pass only the value
//
// folly::dynamic (no conversion)
template <typename Fn>
EnableForArgTypes<Fn, folly::dynamic> invokeForKeyValue(
    Fn fn, const folly::dynamic&, const folly::dynamic& v) {}
// int64_t
template <typename Fn>
EnableForArgTypes<Fn, int64_t> invokeForKeyValue(
    Fn fn, const folly::dynamic&, const folly::dynamic& v) {}
// bool
template <typename Fn>
EnableForArgTypes<Fn, bool> invokeForKeyValue(
    Fn fn, const folly::dynamic&, const folly::dynamic& v) {}
// double
template <typename Fn>
EnableForArgTypes<Fn, double> invokeForKeyValue(
    Fn fn, const folly::dynamic&, const folly::dynamic& v) {}
// std::string
template <typename Fn>
EnableForArgTypes<Fn, std::string> invokeForKeyValue(
    Fn fn, const folly::dynamic&, const folly::dynamic& v) {}

//
// 2 arguments -- pass both the key and the value.
//

// Pass the key as folly::dynamic, without conversion
//
// folly::dynamic, folly::dynamic (no conversion of value, either)
template <typename Fn>
EnableForArgTypes<Fn, folly::dynamic, folly::dynamic> invokeForKeyValue(
    Fn fn, const folly::dynamic& k, const folly::dynamic& v) {}
// folly::dynamic, int64_t
template <typename Fn>
EnableForArgTypes<Fn, folly::dynamic, int64_t> invokeForKeyValue(
    Fn fn, const folly::dynamic& k, const folly::dynamic& v) {}
// folly::dynamic, bool
template <typename Fn>
EnableForArgTypes<Fn, folly::dynamic, bool> invokeForKeyValue(
    Fn fn, const folly::dynamic& k, const folly::dynamic& v) {}
// folly::dynamic, double
template <typename Fn>
EnableForArgTypes<Fn, folly::dynamic, double> invokeForKeyValue(
    Fn fn, const folly::dynamic& k, const folly::dynamic& v) {}
// folly::dynamic, std::string
template <typename Fn>
EnableForArgTypes<Fn, folly::dynamic, std::string> invokeForKeyValue(
    Fn fn, const folly::dynamic& k, const folly::dynamic& v) {}

// Convert the key to std::string.
//
// std::string, folly::dynamic (no conversion of value)
template <typename Fn>
EnableForArgTypes<Fn, std::string, folly::dynamic> invokeForKeyValue(
    Fn fn, const folly::dynamic& k, const folly::dynamic& v) {}
// std::string, int64_t
template <typename Fn>
EnableForArgTypes<Fn, std::string, int64_t> invokeForKeyValue(
    Fn fn, const folly::dynamic& k, const folly::dynamic& v) {}
// std::string, bool
template <typename Fn>
EnableForArgTypes<Fn, std::string, bool> invokeForKeyValue(
    Fn fn, const folly::dynamic& k, const folly::dynamic& v) {}
// std::string, double
template <typename Fn>
EnableForArgTypes<Fn, std::string, double> invokeForKeyValue(
    Fn fn, const folly::dynamic& k, const folly::dynamic& v) {}
// std::string, std::string
template <typename Fn>
EnableForArgTypes<Fn, std::string, std::string> invokeForKeyValue(
    Fn fn, const folly::dynamic& k, const folly::dynamic& v) {}

// Convert the key to int64_t (good for arrays).
//
// int64_t, folly::dynamic (no conversion of value)
template <typename Fn>
EnableForArgTypes<Fn, int64_t, folly::dynamic> invokeForKeyValue(
    Fn fn, const folly::dynamic& k, const folly::dynamic& v) {}
// int64_t, int64_t
template <typename Fn>
EnableForArgTypes<Fn, int64_t, int64_t> invokeForKeyValue(
    Fn fn, const folly::dynamic& k, const folly::dynamic& v) {}
// int64_t, bool
template <typename Fn>
EnableForArgTypes<Fn, int64_t, bool> invokeForKeyValue(
    Fn fn, const folly::dynamic& k, const folly::dynamic& v) {}
// int64_t, double
template <typename Fn>
EnableForArgTypes<Fn, int64_t, double> invokeForKeyValue(
    Fn fn, const folly::dynamic& k, const folly::dynamic& v) {}
// int64_t, std::string
template <typename Fn>
EnableForArgTypes<Fn, int64_t, std::string> invokeForKeyValue(
    Fn fn, const folly::dynamic& k, const folly::dynamic& v) {}
} // namespace detail

template <typename Fn>
void DynamicParser::optional(const folly::dynamic& key, Fn fn) {}

//
// Implementation of DynamicParser template & inline methods.
//

template <typename Fn>
void DynamicParser::required(const folly::dynamic& key, Fn fn) {}

template <typename Fn>
void DynamicParser::objectItems(Fn fn) {}

template <typename Fn>
void DynamicParser::arrayItems(Fn fn) {}

template <typename Fn>
void DynamicParser::wrapError(const folly::dynamic* lookup_k, Fn fn) {}

template <typename Fn>
void DynamicParser::parse(
    const folly::dynamic& k, const folly::dynamic& v, Fn fn) {}

inline const folly::dynamic& DynamicParser::ParserStack::key() const {}

inline const folly::dynamic& DynamicParser::ParserStack::value() const {}

} // namespace folly