summaryrefslogtreecommitdiff
path: root/modules/tools/examples/cli_mod.cpp
blob: 404b2eff3ac570bae07358b43440e82684db7fce (plain)
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;
}