diff options
author | Claudius 'keldu' Holeksa <mail@keldu.de> | 2024-07-29 16:44:10 +0200 |
---|---|---|
committer | Claudius 'keldu' Holeksa <mail@keldu.de> | 2024-07-29 16:44:10 +0200 |
commit | 2a9b7c5a542f37d5115eb9c22d91b4b81a04085f (patch) | |
tree | 74d9ca6475d4db6bb62f6554f6bf8b0378a62042 /modules/codec | |
parent | 78976675150e427efd3aef7c140bb4c308469b90 (diff) |
wip args
Diffstat (limited to 'modules/codec')
-rw-r--r-- | modules/codec/c++/args.hpp | 44 | ||||
-rw-r--r-- | modules/codec/tests/args.cpp | 55 |
2 files changed, 89 insertions, 10 deletions
diff --git a/modules/codec/c++/args.hpp b/modules/codec/c++/args.hpp index eb13459..78664c8 100644 --- a/modules/codec/c++/args.hpp +++ b/modules/codec/c++/args.hpp @@ -1,6 +1,9 @@ #pragma once #include "schema.hpp" +#include "data.hpp" + +#include <algorithm> namespace saw { namespace encode { @@ -32,17 +35,17 @@ public: argc_{argc} {} - size_t size() const { + uint64_t size() const { if(argc_ < 0){ - return 0; + return 0u; } - static_assert(sizeof(int) <= sizeof(size_t), "size_t is smaller than int"); + static_assert(sizeof(int) <= sizeof(uint64_t), "size_t is smaller than int"); - return static_cast<size_t>(argc_); + return static_cast<uint64_t>(argc_); } - std::string_view arg_view(size_t i){ + std::string_view arg_view(uint64_t i){ if(i < size()){ return std::string_view{argv_[i]}; } @@ -63,17 +66,37 @@ struct args_decode<schema::Args<schema::Struct<schema::Member<Str,Lits>...>,sche schema::Tuple<Tup...> >; + using SchemaStruct = schema::Struct<schema::Member<Str,Lits>...>; + using SchemaTuple = schema::Tuple<Tup...>; + + template<uint64_t i> + static error_or<void> decode_struct_member(data<Schema, ToDec>& to, std::string_view name, std::string_view value){ + if constexpr ( i < sizeof...(Str) ) { + static constexpr string_literal Literal = parameter_key_pack_type<i,Lits...>::literal; + + if(Literal.view() == name){ + auto& target = to.template get<Literal>(); + /// @TODO + return void_t{}; + } + + return decode_struct_member<i+1u>(to, name, value); + } + return make_error<err::not_found>{"Couldn't decode argument"}; + } + static error_or<void> decode(data<Schema, encode::Args>& from, data<Schema,ToDec>& to){ if(from.size() == 0){ return make_error<err::invalid_state>(); } - to.get<"program">().set(std::string{from.arg_view(0)}); + to.template get<"program">().set(std::string{from.arg_view(0)}); std::size_t tuple_pos = 0; for(size_t i = 1; i < from.size(); ++i){ auto view = from.arg_view(i); if(view.starts_with("--")){ - view.remove_prefix(std::min(2u, view.size())); + auto min_val = view.size() > 2u ? 2u : view.size(); + view.remove_prefix(min_val); ++i; if( i >= from.size() ){ @@ -82,12 +105,12 @@ struct args_decode<schema::Args<schema::Struct<schema::Member<Str,Lits>...>,sche auto value_view = from.arg_view(i); - auto eov = decode_struct_member<0>(to.get<"args">(), view, value_view); + auto eov = decode_struct_member<0>(to.template get<"args">(), view, value_view); if(eov.is_error()){ return eov; } } else { - auto eov = decode_tuple_member<0>(to.get<"positionals">(), view); + auto eov = decode_tuple_member<0>(to.template get<"positionals">(), view); if(eov.is_error()){ return eov; } @@ -117,7 +140,8 @@ public: std::vector<name_and_value> navs; std::vector<std::string> positionals; - return void_t{}; + auto eov = impl::args_decode<Schema,ToDec>::decode(from,to); + return eov; } }; } diff --git a/modules/codec/tests/args.cpp b/modules/codec/tests/args.cpp new file mode 100644 index 0000000..ed6d918 --- /dev/null +++ b/modules/codec/tests/args.cpp @@ -0,0 +1,55 @@ +#include <forstio/test/suite.hpp> +#include "../c++/args.hpp" + +namespace { +namespace sch { +using namespace saw::schema; + +using ArgsStruct = Struct< + Member<String, "file"> +>; + +using ArgsTuple = Tuple< + Int32, + String +>; +} + +SAW_TEST("Codec Args Decode"){ + using namespace saw; + + using Schema = sch::Args<sch::ArgsStruct, sch::ArgsTuple>; + + std::array<std::string, 5> foo { + "example", + "5", + "--file", + "./foo.bar", + "ex" + }; + std::array<char*,5> bar; + for(uint64_t i = 0; i < bar.size(); ++i){ + bar[i] = &foo[i][0]; + } + + data<sch::Args<sch::ArgsStruct, sch::ArgsTuple>,encode::Args> dat_args{ + &bar[0],5 + }; + data<sch::Args<sch::ArgsStruct, sch::ArgsTuple>> dat_nat; + + codec<sch::Args<sch::ArgsStruct, sch::ArgsTuple>, encode::Args> args_codec; + + auto eov = args_codec.decode(dat_args, dat_nat); + SAW_EXPECT(eov.is_value(), "Couldn't decode data"); + + auto& prog = dat_nat.template get<"program">(); + auto& str = dat_nat.template get<"args">(); + auto& tup = dat_nat.template get<"positionals">(); + + SAW_EXPECT(prog == "example", "Wrong program name"); + SAW_EXPECT(str.template get<"file">() == "./foo.bar", "Wrong file path parsing"); + SAW_EXPECT(tup.template get<0>() == data<sch::Int32>{5}, "Wrong number"); + SAW_EXPECT(tup.template get<1>() == "ex", "Wrong String"); +} + +} |