1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
#include "../c++/cli_analyzer.hpp"
#include <forstio/codec/simple.hpp>
#include <filesystem>
#include <fstream>
#include <iostream>
namespace schema {
using namespace saw::schema;
using AnalyzeInner = Struct<
Member<String, "bar">,
Member<String, "baz">
>;
using AnalyzeTest = Struct<
Member<String, "foo">,
Member<AnalyzeInner, "inner">
>;
}
std::deque<std::string> split_schema_path(const std::string_view& sch_arg){
std::deque<std::string> split;
bool escape = false;
uint64_t last_pick = 0;
for(uint64_t i = 0; i < sch_arg.size(); ++i){
if(escape){
escape = false;
} else {
if(sch_arg.at(i) == '\\'){
escape = true;
}else if(sch_arg.at(i) == '.'){
std::string sub_str{sch_arg.substr(last_pick, i - last_pick)};
if(sub_str.empty()){
/// @todo return error
return {};
}
split.emplace_back(std::move(sub_str));
last_pick = i+1u;
}
}
}
if( ( sch_arg.size() == last_pick ) || escape ){
return {};
}
std::string sub_str{sch_arg.substr(last_pick)};
split.emplace_back(std::move(sub_str));
return split;
}
int main(int argc, char** argv){
/**
* Basic checking and wrapping args into an array of string_view
* 1. mode
* 2. file_path
* 3. schema_path
* 4. data if it's write
*/
int min_amount_args = 3;
if( argc < (min_amount_args + 1) ) {
std::cerr<<"Not enough arguments"<<std::endl;
return -1;
}
if(argc > 32){
std::cerr<<"Too many arguments"<<std::endl;
return -1;
}
std::array<std::string_view, 32> args_view;
for(int i = 0; i < argc; ++i){
args_view.at(i) = {argv[i]};
}
uint64_t args_size = [&]() -> uint64_t{
if(args_view.at(1) == "r"){
return min_amount_args;
}else if (args_view.at(1) == "w"){
return min_amount_args + 1u;
}else if (args_view.at(1) == "l"){
return min_amount_args;
}
return 0u;
}();
if(args_size < min_amount_args){
std::cerr<<"Invalid first argument. Must either be 'r', 'w' or 'l'."<<std::endl;
return -1;
}
if( (1u+args_size) != ( static_cast<uint64_t>(argc) ) ){
std::cerr<<"Invalid amount argument. Need "<<args_size<<" arguments. Have "<<(argc-1)<<std::endl;
return -1;
}
std::string_view mode = [&]() -> std::string_view {
return args_view.at(1);
}();
std::string json_data;
if ( mode == "w" ){
json_data = std::string{args_view.at(4)};
}
std::deque<std::string> sch_path = split_schema_path(args_view.at(3));
{
auto eov = saw::modify_data_on_cli<schema::AnalyzeTest, saw::encode::Json>(mode, args_view.at(2), sch_path, json_data);
if(eov.is_error()){
auto& err = eov.get_error();
std::cerr<<"Modification failed: "<<err.get_category()<<" - "<<err.get_message()<<std::endl;
return err.get_id();
}
}
if( mode == "r" or mode == "l" ){
std::cout<<json_data<<std::endl;
}
return 0;
}
|