summaryrefslogtreecommitdiff
path: root/modules/codec
diff options
context:
space:
mode:
authorClaudius 'keldu' Holeksa <mail@keldu.de>2024-07-31 15:53:21 +0200
committerClaudius 'keldu' Holeksa <mail@keldu.de>2024-07-31 15:53:21 +0200
commitb0554a3dd0ea14d2d84f3d0e9fa7f22ff1c04175 (patch)
tree9ef43e924960a359747fd8e9a73f18f506444b17 /modules/codec
parent32004c2a672f99ee5c242c2c84d30e00bb31cf25 (diff)
Basic Arg parsing support
Diffstat (limited to 'modules/codec')
-rw-r--r--modules/codec/c++/args.hpp65
-rw-r--r--modules/codec/tests/args.cpp2
2 files changed, 58 insertions, 9 deletions
diff --git a/modules/codec/c++/args.hpp b/modules/codec/c++/args.hpp
index a2b338b..e3e651d 100644
--- a/modules/codec/c++/args.hpp
+++ b/modules/codec/c++/args.hpp
@@ -4,6 +4,7 @@
#include "data.hpp"
#include <algorithm>
+#include <charconv>
namespace saw {
namespace encode {
@@ -59,6 +60,42 @@ struct args_decode {
static_assert(always_false<T,ToDec>, "Not supported");
};
+template<typename T, uint64_t N, typename ToDec>
+struct args_decode<schema::Primitive<T,N>, ToDec> {
+ using Schema = schema::Primitive<T,N>;
+
+ static error_or<void> decode(data<Schema, ToDec>& to, std::string_view view){
+ if(view.empty()){
+ return make_error<err::invalid_state>("Can't decode empty data.");
+ }
+ typename native_data_type<Schema>::type val{};
+ auto fc_res = std::from_chars(view.data(), view.data()+view.size(), val);
+ if(fc_res.ec != std::errc{}){
+ auto err_bld = error_builder{[&](){
+ return std::string{"Parsing of failed: "} + std::string{view};
+ }};
+ return err_bld.template make_error<err::invalid_state>("Parsing failed. ");
+ }
+ to.set(val);
+
+ return make_void();
+ }
+};
+
+template<typename ToDec>
+struct args_decode<schema::String, ToDec> {
+ using Schema = schema::String;
+
+ static error_or<void> decode(data<Schema, ToDec>& to, std::string_view view){
+ try{
+ to.set(std::string{view});
+ }catch(const std::exception&){
+ return make_error<err::out_of_memory>();
+ }
+ return make_void();
+ }
+};
+
template<typename... Str, string_literal... Lits, typename... Tup, typename ToDec>
struct args_decode<schema::Args<schema::Struct<schema::Member<Str,Lits>...>,schema::Tuple<Tup...>>,ToDec> {
using Schema = schema::Args<
@@ -73,11 +110,12 @@ struct args_decode<schema::Args<schema::Struct<schema::Member<Str,Lits>...>,sche
static error_or<void> decode_struct_member(data<SchemaStruct, 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;
+ using StrT = typename parameter_pack_type<i,Str...>::type;
if(Literal.view() == name){
auto& target = to.template get<Literal>();
- /// @TODO
- return void_t{};
+ auto eov = args_decode<StrT, ToDec>::decode(target, value);
+ return eov;
}
return decode_struct_member<i+1u>(to, name, value);
@@ -86,9 +124,17 @@ struct args_decode<schema::Args<schema::Struct<schema::Member<Str,Lits>...>,sche
}
template<uint64_t i>
- static error_or<void> decode_tuple_member(data<SchemaTuple, ToDec>& to, std::string_view value){
-
- return make_error<err::not_implemented>();
+ static error_or<void> decode_tuple_member(data<SchemaTuple, ToDec>& to, uint64_t ptr_i, std::string_view value){
+ if constexpr ( i < sizeof...(Tup) ){
+ if ( i == ptr_i ){
+ using TupT = typename parameter_pack_type<i,Tup...>::type;
+ auto& target = to.template get<i>();
+
+ return args_decode<TupT, ToDec>::decode(target, value);
+ }
+ return decode_tuple_member<i+1u>(to, ptr_i, value);
+ }
+ return make_error<err::invalid_state>("Too many positional arguments.");
}
static error_or<void> decode(data<Schema, encode::Args>& from, data<Schema,ToDec>& to){
@@ -97,7 +143,8 @@ struct args_decode<schema::Args<schema::Struct<schema::Member<Str,Lits>...>,sche
}
to.template get<"program">().set(std::string{from.arg_view(0)});
- std::size_t tuple_pos = 0;
+ uint64_t tuple_pos = 0;
+
for(size_t i = 1; i < from.size(); ++i){
auto view = from.arg_view(i);
if(view.starts_with("--")){
@@ -116,7 +163,7 @@ struct args_decode<schema::Args<schema::Struct<schema::Member<Str,Lits>...>,sche
return eov;
}
} else {
- auto eov = decode_tuple_member<0>(to.template get<"positionals">(), view);
+ auto eov = decode_tuple_member<0>(to.template get<"positionals">(), tuple_pos, view);
if(eov.is_error()){
return eov;
}
@@ -125,7 +172,7 @@ struct args_decode<schema::Args<schema::Struct<schema::Member<Str,Lits>...>,sche
}
if(tuple_pos != sizeof...(Tup)){
- return make_error<err::invalid_state>();
+ return make_error<err::invalid_state>("Didn't parse the whole set of positionals.");
}
return void_t{};
@@ -138,6 +185,7 @@ class codec<Schema, encode::Args> {
public:
template<typename ToDec>
error_or<void> decode(data<Schema, encode::Args>& from, data<Schema, ToDec>& to){
+ /*
struct name_and_value {
std::string name;
std::string value;
@@ -145,6 +193,7 @@ public:
std::string program;
std::vector<name_and_value> navs;
std::vector<std::string> positionals;
+ */
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
index ed6d918..f53b80e 100644
--- a/modules/codec/tests/args.cpp
+++ b/modules/codec/tests/args.cpp
@@ -40,7 +40,7 @@ SAW_TEST("Codec Args Decode"){
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");
+ SAW_EXPECT(eov.is_value(), std::string{"Couldn't decode data. "} + std::string{eov.get_error().get_category()} + std::string{" - "} + std::string{eov.get_error().get_message()});
auto& prog = dat_nat.template get<"program">();
auto& str = dat_nat.template get<"args">();