Skip to content
This repository was archived by the owner on Nov 5, 2024. It is now read-only.

Commit 838f80b

Browse files
committed
extract custom decoder into a separate file
1 parent 0202b3d commit 838f80b

File tree

2 files changed

+90
-78
lines changed

2 files changed

+90
-78
lines changed

custom_decoder.h

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#ifndef LIB_RUBY_PARSER_NODE_CUSTOM_DECODER_H
2+
#define LIB_RUBY_PARSER_NODE_CUSTOM_DECODER_H
3+
4+
#include <napi.h>
5+
#include "lib-ruby-parser.h"
6+
7+
namespace lib_ruby_parser_node
8+
{
9+
10+
class JsCustomDecoder : public lib_ruby_parser::CustomDecoder
11+
{
12+
public:
13+
struct DecodeError
14+
{
15+
bool has_error;
16+
std::string error;
17+
};
18+
19+
Napi::FunctionReference callback;
20+
std::shared_ptr<DecodeError> error;
21+
22+
JsCustomDecoder(const Napi::Function &callback, std::shared_ptr<DecodeError> error)
23+
{
24+
this->callback = Napi::Persistent(callback);
25+
this->error = error;
26+
}
27+
28+
Napi::Env env()
29+
{
30+
return this->callback.Env();
31+
}
32+
33+
virtual Result rewrite(std::string encoding, lib_ruby_parser::Bytes input)
34+
{
35+
Napi::Value raw_response = callback.Call({
36+
Napi::String::New(env(), encoding),
37+
convert(std::move(input), env()),
38+
});
39+
if (!raw_response.IsObject())
40+
return JsError("response must be an object");
41+
42+
Napi::Object response = raw_response.As<Napi::Object>();
43+
44+
Napi::Value success = response.Get("success");
45+
if (!success.IsBoolean())
46+
return JsError("'success' field must be true/false");
47+
48+
if (success.ToBoolean().Value())
49+
{
50+
// success, consume 'output' field
51+
if (!response.Get("output").IsArray())
52+
return JsError("'output' field must be an array");
53+
54+
Napi::Array output = response.Get("output").As<Napi::Array>();
55+
auto ptr = (char *)malloc(output.Length());
56+
for (size_t i = 0; i < output.Length(); i++)
57+
{
58+
Napi::Value byte = output[i];
59+
if (!byte.IsNumber())
60+
{
61+
return JsError("'output' field contains invalid byte");
62+
}
63+
ptr[i] = byte.ToNumber().Int32Value();
64+
}
65+
return Result::Ok(lib_ruby_parser::Bytes(ptr, output.Length()));
66+
}
67+
else
68+
{
69+
// error, consume 'error' field
70+
if (!response.Get("error").IsString())
71+
return JsError("'error' field must be a string");
72+
73+
Napi::String error = Napi::String::New(env(), response.Get("error").ToString().Utf8Value());
74+
return Result::Error(error);
75+
}
76+
}
77+
virtual ~JsCustomDecoder() {}
78+
79+
Result JsError(std::string message)
80+
{
81+
this->error->has_error = true;
82+
this->error->error = "custom_rewriter: " + message;
83+
return Result::Error(message);
84+
}
85+
};
86+
87+
} // namespace lib_ruby_parser_node
88+
89+
#endif // LIB_RUBY_PARSER_NODE_CUSTOM_DECODER_H

node_bindings.cc

Lines changed: 1 addition & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,13 @@
11
#include <napi.h>
22
#include "lib-ruby-parser.h"
33
#include "convert.h"
4+
#include "custom_decoder.h"
45
#include <iostream>
56
#include <variant>
67
#include <tuple>
78

89
namespace lib_ruby_parser_node
910
{
10-
11-
class JsCustomDecoder : public lib_ruby_parser::CustomDecoder
12-
{
13-
public:
14-
struct DecodeError
15-
{
16-
bool has_error;
17-
std::string error;
18-
};
19-
20-
Napi::FunctionReference callback;
21-
std::shared_ptr<DecodeError> error;
22-
23-
JsCustomDecoder(const Napi::Function &callback, std::shared_ptr<DecodeError> error)
24-
{
25-
this->callback = Napi::Persistent(callback);
26-
this->error = error;
27-
}
28-
29-
Napi::Env env()
30-
{
31-
return this->callback.Env();
32-
}
33-
34-
virtual Result rewrite(std::string encoding, lib_ruby_parser::Bytes input)
35-
{
36-
Napi::Value raw_response = callback.Call({
37-
Napi::String::New(env(), encoding),
38-
convert(std::move(input), env()),
39-
});
40-
if (!raw_response.IsObject())
41-
return JsError("response must be an object");
42-
43-
Napi::Object response = raw_response.As<Napi::Object>();
44-
45-
Napi::Value success = response.Get("success");
46-
if (!success.IsBoolean())
47-
return JsError("'success' field must be true/false");
48-
49-
if (success.ToBoolean().Value())
50-
{
51-
// success, consume 'output' field
52-
if (!response.Get("output").IsArray())
53-
return JsError("'output' field must be an array");
54-
55-
Napi::Array output = response.Get("output").As<Napi::Array>();
56-
auto ptr = (char *)malloc(output.Length());
57-
for (size_t i = 0; i < output.Length(); i++)
58-
{
59-
Napi::Value byte = output[i];
60-
if (!byte.IsNumber())
61-
{
62-
return JsError("'output' field contains invalid byte");
63-
}
64-
ptr[i] = byte.ToNumber().Int32Value();
65-
}
66-
return Result::Ok(lib_ruby_parser::Bytes(ptr, output.Length()));
67-
}
68-
else
69-
{
70-
// error, consume 'error' field
71-
if (!response.Get("error").IsString())
72-
return JsError("'error' field must be a string");
73-
74-
Napi::String error = Napi::String::New(env(), response.Get("error").ToString().Utf8Value());
75-
return Result::Error(error);
76-
}
77-
}
78-
virtual ~JsCustomDecoder() {}
79-
80-
Result JsError(std::string message)
81-
{
82-
this->error->has_error = true;
83-
this->error->error = "custom_rewriter: " + message;
84-
return Result::Error(message);
85-
}
86-
};
87-
8811
Napi::Value JsThrow(Napi::Env env, std::string message)
8912
{
9013
Napi::TypeError::New(env, message).ThrowAsJavaScriptException();

0 commit comments

Comments
 (0)