Skip to content

Commit

Permalink
Fold JSON value into config entry class.
Browse files Browse the repository at this point in the history
  • Loading branch information
ColinH committed Mar 30, 2024
1 parent 76d666a commit 7322fc2
Show file tree
Hide file tree
Showing 39 changed files with 975 additions and 853 deletions.
9 changes: 6 additions & 3 deletions include/tao/config/contrib/rot13.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@

#include <string>

#include "../internal/atom.hpp"
#include "../internal/pegtl.hpp"

namespace tao::config
{
[[nodiscard]] std::string rot13( const std::string& in )
[[nodiscard]] inline internal::string_t rot13( const pegtl::position& pos, const std::string& in )
{
std::string out( in );
internal::string_t out( in, pos );

for( char& c : out ) {
for( char& c : out.value ) {
if( ( ( 'a' <= c ) && ( c <= 'm' ) ) || ( ( 'A' <= c ) && ( c <= 'M' ) ) ) {
c += 13;
}
Expand Down
5 changes: 5 additions & 0 deletions include/tao/config/internal/array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ namespace tao::config::internal
basic_array& operator=( basic_array&& ) = default;
basic_array& operator=( const basic_array& ) = default;

[[nodiscard]] const pegtl::position& get_position() const noexcept
{
return position;
}

std::string function;
std::list< C > array;
pegtl::position position;
Expand Down
58 changes: 58 additions & 0 deletions include/tao/config/internal/atom.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (c) 2024 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/config/

#ifndef TAO_CONFIG_INTERNAL_ATOM_HPP
#define TAO_CONFIG_INTERNAL_ATOM_HPP

#include <cstdint>
#include <string>
#include <utility>
#include <vector>

#include "pegtl.hpp"

namespace tao::config::internal
{
struct null
{
explicit null( const pegtl::position& pos )
: position( pos )
{}

[[nodiscard]] const pegtl::position& get_position() const noexcept
{
return position;
}

pegtl::position position;
};

template< typename T >
struct atom
{
template< typename V >
atom( V&& v, const pegtl::position& pos )
: value( std::forward< V >( v ) ),
position( pos )
{}

[[nodiscard]] const pegtl::position& get_position() const noexcept
{
return position;
}

T value;
pegtl::position position;
};

using boolean = atom< bool >;
using string_t = atom< std::string >;
using binary_t = atom< std::vector< std::byte > >;

using signed_t = atom< std::int64_t >;
using unsigned_t = atom< std::uint64_t >;
using double_t = atom< double >;

} // namespace tao::config::internal

#endif
39 changes: 10 additions & 29 deletions include/tao/config/internal/concat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <string>
#include <utility>

#include "constants.hpp"
#include "entry_kind.hpp"
#include "forward.hpp"
#include "json.hpp"
Expand Down Expand Up @@ -45,48 +46,28 @@ namespace tao::config::internal
return implicit || temporary || concat.empty();
}

[[nodiscard]] const json_t* get_value() const
{
const json_t* result = nullptr;

for( const auto& e : concat ) {
switch( e.kind() ) {
case entry_kind::value:
if( result != nullptr ) {
return nullptr;
}
result = &e.get_value();
continue;
case entry_kind::reference:
throw std::logic_error( "code should be unreachable" ); // LCOV_EXCL_LINE
case entry_kind::array:
throw pegtl::parse_error( "array as referenced reference part", e.get_array().position );
case entry_kind::object:
throw pegtl::parse_error( "object as referenced reference part", e.get_object().position );
case entry_kind::concat:
throw pegtl::parse_error( "concat as referenced reference part", e.get_concat().position );
}
throw std::logic_error( "code should be unreachable" ); // LCOV_EXCL_LINE
}
return result;
}

void back_ensure_kind( const entry_kind k, const pegtl::position& p )
template< typename T >
void back_ensure_init( const T k, const pegtl::position& p )
{
if( concat.empty() ) {
concat.emplace_back( k, p );
}
else if( concat.back().kind() != k ) {
else if( concat.back().kind() != T::kind ) {
concat.emplace_back( k, p );
}
}

void back_emplace_func( const std::string& name, const pegtl::position& p )
{
back_ensure_kind( entry_kind::array, p );
back_ensure_init( array_init, p );
concat.back().get_array().function = name;
}

[[nodiscard]] const pegtl::position& get_position() const noexcept
{
return position;
}

bool remove = false; // Whether generated by += (false) or by = (true), because in the latter case everything that comes before must be removed.
bool implicit = false; // Whether implicitly generated by a delete, e.g. a.b.c = delete when a.b doesn't even exist, so it's implicitly generated to set the remove flag on a.b.c.
bool temporary = false; // Whether flagged as temporary by the user, i.e. this is not to be included in the final result and will be omitted by phase3.
Expand Down
4 changes: 2 additions & 2 deletions include/tao/config/internal/config_action.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ namespace tao::config::internal
static void apply( Input& in, State& st, const function_map& /*unused*/ )
{
const auto p = in.position();
const auto f = [ & ]( concat& c ) { c.back_ensure_kind( entry_kind::array, p ); };
const auto f = [ & ]( concat& c ) { c.back_ensure_init( array_init, p ); };
phase1_append( st.root, st.prefix + st.suffix, f, phase1_mode::manifest );
}
};
Expand All @@ -60,7 +60,7 @@ namespace tao::config::internal
static void apply( Input& in, State& st, const function_map& /*unused*/ )
{
const auto p = in.position();
const auto f = [ & ]( concat& c ) { c.back_ensure_kind( entry_kind::object, p ); };
const auto f = [ & ]( concat& c ) { c.back_ensure_init( object_init, p ); };
phase1_append( st.root, st.prefix + st.suffix, f, phase1_mode::manifest );
}
};
Expand Down
8 changes: 6 additions & 2 deletions include/tao/config/internal/config_grammar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#define TAO_CONFIG_INTERNAL_CONFIG_GRAMMAR_HPP

#include "forward.hpp"
#include "jaxn_action.hpp"
#include "jaxn_to_entry.hpp"
#include "json.hpp"
#include "key1_grammar.hpp"
#include "key1_guard.hpp"
Expand All @@ -29,8 +31,10 @@ namespace tao::config::internal::rules
typename State >
[[nodiscard]] static bool match( pegtl_input_t& in, State& st, const function_map& /*unused*/ )
{
const auto j = parse_jaxn( in );
const auto f = [ & ]( concat& c ) { c.concat.emplace_back( j ); };
jaxn_to_entry consumer;
pegtl::parse< pegtl::must< json::jaxn::internal::rules::sor_single_value >, jaxn_action, json::jaxn::internal::errors >( in, consumer );
// assert( consumer.value.has_value() );
const auto f = [ &e = *consumer.value ]( concat& c ) { c.concat.emplace_back( std::move( e ) ); };
phase1_append( st.root, st.prefix + st.suffix, f, phase1_mode::manifest );
return true;
}
Expand Down
11 changes: 5 additions & 6 deletions include/tao/config/internal/config_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include "function_implementations.hpp"
#include "function_wrapper.hpp"
#include "json.hpp"
#include "json_traits.hpp"
#include "pegtl.hpp"
#include "phase2_everything.hpp"
#include "phase3_remove.hpp"
Expand All @@ -29,18 +28,18 @@ namespace tao::config::internal
{
config_parser()
: fm( { { "binary", wrap( binary_function ) },
{ "cbor", wrap( cbor_function ) },
// { "cbor", wrap( cbor_function ) },
{ "default", wrap( default_function ) },
{ "env", wrap( env_function ) },
{ "env?", wrap( env_if_function ) },
{ "jaxn", wrap( jaxn_function ) },
{ "json", wrap( json_function ) },
{ "msgpack", wrap( msgpack_function ) },
// { "json", wrap( json_function ) },
// { "msgpack", wrap( msgpack_function ) },
{ "read", wrap( read_function ) },
{ "shell", wrap( shell_function ) },
{ "split", wrap( split_function ) },
{ "string", wrap( string_function ) },
{ "ubjson", wrap( ubjson_function ) } } )
{ "string", wrap( string_function ) } } )
//{ "ubjson", wrap( ubjson_function ) } } )
{}

config_parser( config_parser&& ) = delete;
Expand Down
35 changes: 31 additions & 4 deletions include/tao/config/internal/constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,53 @@
#ifndef TAO_CONFIG_INTERNAL_CONSTANTS_HPP
#define TAO_CONFIG_INTERNAL_CONSTANTS_HPP

#include "entry_kind.hpp"

namespace tao::config::internal
{
struct part_star_t
struct part_asterisk_t
{
explicit constexpr part_star_t( int /*unused*/ ) {}
explicit constexpr part_asterisk_t( int /*unused*/ ) {}
};

struct part_vector_t
{
explicit constexpr part_vector_t( int /*unused*/ ) {}
};

constexpr part_star_t part_star{ 0 };
constexpr part_asterisk_t part_asterisk{ 0 };
constexpr part_vector_t part_vector{ 0 };

constexpr bool operator<( const part_star_t, const part_star_t ) noexcept
[[nodiscard]] constexpr bool operator<( const part_asterisk_t, const part_asterisk_t ) noexcept
{
return false;
}

struct array_init_t
{
explicit constexpr array_init_t( int /*unused*/ ) {}

static constexpr entry_kind kind = entry_kind::ARRAY;
};

struct object_init_t
{
explicit constexpr object_init_t( int /*unused*/ ) {}

static constexpr entry_kind kind = entry_kind::OBJECT;
};

struct asterisk_init_t
{
explicit constexpr asterisk_init_t( int /*unused*/ ) {}

static constexpr entry_kind kind = entry_kind::ASTERISK;
};

constexpr array_init_t array_init{ 0 };
constexpr object_init_t object_init{ 0 };
constexpr asterisk_init_t asterisk_init{ 0 };

} // namespace tao::config::internal

#endif
Loading

0 comments on commit 7322fc2

Please sign in to comment.