Skip to content

Commit

Permalink
Refactor code, add throw error function
Browse files Browse the repository at this point in the history
  • Loading branch information
navrocky committed Jan 23, 2025
1 parent 81485e2 commit 4f159c3
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 78 deletions.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@ if(CMAKE_BUILD_TYPE STREQUAL "Release")
endif()

set(SOURCES
src/inja_renderer.cpp
src/inja_renderer.h
src/main.cpp
src/mstch_renderer.cpp
src/mstch_renderer.h
src/tools.cpp
src/tools.h
)

add_executable(${TARGET} ${SOURCES})
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ Additional functions:
```
split(text: string, delimiter: string): string
```

- Throw error:

```
error(message: string)
```

## Mstch examples

Expand Down
35 changes: 35 additions & 0 deletions src/inja_renderer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "inja_renderer.h"

#include <inja/inja.hpp>
#include <stdexcept>

#include "tools.h"

using namespace std;
using namespace std::placeholders;

inja::json split(const inja::Arguments& args)
{
if (args.size() != 2)
throw runtime_error("Expected 2 parameters: split(s: string, delimiter: string)");
auto s = args[0]->get<string>();
auto delimiter = args[1]->get<string>();
return stringSplit(s, delimiter);
}

inja::json error(const inja::Arguments& args)
{
if (args.size() != 1)
throw runtime_error("Expected 1 parameters: error(message: string)");
auto message = args[0]->get<string>();
throw runtime_error(message);
}

string renderWithInja(const string& tmpl, char** envp)
{
auto envs = getAllEnvs<inja::json>(envp);
inja::Environment env;
env.add_callback("split", bind(split, _1));
env.add_callback("error", bind(split, _1));
return env.render(tmpl, envs);
}
5 changes: 5 additions & 0 deletions src/inja_renderer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#include <string>

std::string renderWithInja(const std::string& tmpl, char** envp);
82 changes: 4 additions & 78 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,93 +1,19 @@
#include <iostream>
#include <iterator>
#include <sstream>

#include <args-parser/all.hpp>
#include <functional>
#include <inja/inja.hpp>
#include <mstch/mstch.hpp>

#include "inja_renderer.h"
#include "mstch_renderer.h"
#include "tools.h"

using namespace std;
using namespace std::placeholders;
using namespace Args;

string readAllInput()
{
cin >> noskipws;
istream_iterator<char> it(cin);
istream_iterator<char> end;
return string(it, end);
}

struct KeyValue {
string key;
string value;
};

KeyValue parseKeyValue(const string& s)
{
auto i = s.find("=");
if (i == string::npos)
return { .key = s };
return {
.key = s.substr(0, i),
.value = s.substr(i + 1),
};
}

template <typename Map>
Map getAllEnvs(char** envp)
{
Map m;
for (char** env = envp; *env != 0; env++) {
auto kv = parseKeyValue(*env);
m[kv.key] = kv.value;
}
return m;
}

static const char* MSTCH_ENGINE = "mstch";
static const char* INJA_ENGINE = "inja";

string renderWithMstch(const string& tmpl, char** envp)
{
auto envs = getAllEnvs<mstch::map>(envp);
return mstch::render(tmpl, envs);
}

vector<string> stringSplit(const string& s, const string& delimiter)
{
vector<string> res;
if (delimiter.empty()) {
res.push_back(s);
return res;
}
string::size_type prevPos = 0, pos = 0;
while ((pos = s.find(delimiter, pos)) != string::npos) {
res.push_back(s.substr(prevPos, pos - prevPos));
prevPos = ++pos;
}
res.push_back(s.substr(prevPos, pos - prevPos));
return res;
}

inja::json split(const inja::Arguments& args)
{
if (args.size() != 2)
throw runtime_error("Expected 2 parameters: split(s: string, delimiter: string)");
auto s = args[0]->get<string>();
auto delimiter = args[1]->get<string>();
return stringSplit(s, delimiter);
}

string renderWithInja(const string& tmpl, char** envp)
{
auto envs = getAllEnvs<inja::json>(envp);
inja::Environment env;
env.add_callback("split", bind(split, _1));
return env.render(tmpl, envs);
}

int main(int argc, char** argv, char** envp)
{
CmdLine cmd(argc, argv);
Expand Down
11 changes: 11 additions & 0 deletions src/mstch_renderer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "mstch_renderer.h"

#include <mstch/mstch.hpp>

#include "tools.h"

std::string renderWithMstch(const std::string& tmpl, char** envp)
{
auto envs = getAllEnvs<mstch::map>(envp);
return mstch::render(tmpl, envs);
}
5 changes: 5 additions & 0 deletions src/mstch_renderer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#include <string>

std::string renderWithMstch(const std::string& tmpl, char** envp);
41 changes: 41 additions & 0 deletions src/tools.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include "tools.h"

#include <iostream>
#include <iterator>

using namespace std;

KeyValue parseKeyValue(const std::string& s)
{
auto i = s.find("=");
if (i == std::string::npos)
return { .key = s };
return {
.key = s.substr(0, i),
.value = s.substr(i + 1),
};
}

std::string readAllInput()
{
cin >> noskipws;
istream_iterator<char> it(cin);
istream_iterator<char> end;
return string(it, end);
}

vector<string> stringSplit(const string& s, const string& delimiter)
{
vector<string> res;
if (delimiter.empty()) {
res.push_back(s);
return res;
}
string::size_type prevPos = 0, pos = 0;
while ((pos = s.find(delimiter, pos)) != string::npos) {
res.push_back(s.substr(prevPos, pos - prevPos));
prevPos = ++pos;
}
res.push_back(s.substr(prevPos, pos - prevPos));
return res;
}
26 changes: 26 additions & 0 deletions src/tools.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#include <string>
#include <vector>

std::string readAllInput();

struct KeyValue {
std::string key;
std::string value;
};

KeyValue parseKeyValue(const std::string& s);

template <typename Map>
Map getAllEnvs(char** envp)
{
Map m;
for (char** env = envp; *env != 0; env++) {
auto kv = parseKeyValue(*env);
m[kv.key] = kv.value;
}
return m;
}

std::vector<std::string> stringSplit(const std::string& s, const std::string& delimiter);

0 comments on commit 4f159c3

Please sign in to comment.