Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scaffolding associated enums #28

Merged
merged 7 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Scaffolding: Add support for errors
- Scaffolding: Add internal ref counts for object types
- Scaffolding: Add support for associated enums

#### v0.4.1+v0.25.0

Expand Down
8 changes: 3 additions & 5 deletions bindgen/src/bindings/cpp/templates/cpp_scaffolding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
{% else %}
{% endmatch %}

template <class> inline constexpr bool always_false_v = false;

#if defined(_WIN32) || defined(_WIN64)
#define UNIFFI_EXPORT __declspec(dllexport)
#else
Expand Down Expand Up @@ -146,9 +148,7 @@ struct RustStream: std::basic_iostream<uint8_t> {
{% include "scaffolding/err.hpp" %}
{% endfor %}
{%- else %}
{%- if e.is_flat() %}
{% include "enum_conv.hpp" %}
{% endif %}
{%- endif %}
{%- when Type::Object { module_path, name, imp } %}
{% include "scaffolding/obj.hpp" %}
Expand Down Expand Up @@ -303,7 +303,7 @@ UNIFFI_EXPORT
{%- call macros::fn_prologue(ci, func, ffi_func) %}
{% match func.return_type() %}
{% when Some with (return_type) %}
auto ret = obj->{{ func.name() }}(
auto ret = obj->{{ func.name() }}({% if func.takes_self_by_arc() %}obj{% if !func.arguments().is_empty() %},{% endif %}{% endif %}
{%- for arg in func.arguments() %}
{{- arg|lift_fn }}({{ arg.name()|var_name }}){% if !loop.last %}, {% endif -%}
{% endfor %});
Expand Down Expand Up @@ -429,10 +429,8 @@ void rustbuffer_free(RustBuffer& buf) {
{% include "scaffolding/err.cpp" %}
{% endfor %}
{%- else %}
{%- if e.is_flat() %}
{% include "enum_tmpl.cpp" %}
{%- endif %}
{%- endif %}
{%- when Type::Object { module_path, name, imp } %}
{% include "scaffolding/obj.cpp" %}
{%- when Type::CallbackInterface { module_path, name } %}
Expand Down
6 changes: 3 additions & 3 deletions bindgen/src/bindings/cpp/templates/enum_tmpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ RustBuffer {{ ffi_converter_name }}::lower(const {{ type_name }} &val) {
case {{ loop.index }}:
return {{ type_name }}::{{ variant|variant_name }} {
{%- for field in variant.fields() %}
.{{field.name()|var_name}} = uniffi::{{ field|read_fn }}(stream),
.{{field.name()|var_name}} = {{ field|read_fn }}(stream),
{%- endfor %}
};
{% endfor %}
Expand All @@ -93,7 +93,7 @@ void {{ ffi_converter_name }}::write(RustStream &stream, const {{ type_name }} &
{%- for variant in e.variants() %}
{% if !loop.first %}else {% endif %}if constexpr (std::is_same_v<T, {{ type_name }}::{{ variant|variant_name }}>) {
{%- for field in variant.fields() %}
uniffi::{{ field|write_fn }}(stream, arg.{{ field.name()|var_name }});
{{ field|write_fn }}(stream, arg.{{ field.name()|var_name }});
{%- endfor %}
}
{%- endfor %}
Expand All @@ -114,7 +114,7 @@ int32_t {{ ffi_converter_name }}::allocation_size(const {{ type_name|class_name
{% if !loop.first %}else {% endif %}if constexpr (std::is_same_v<T, {{ type_name }}::{{ variant|variant_name }}>) {
int32_t size = 0;
{%- for field in variant.fields() %}
size += uniffi::{{ field|allocation_size_fn }}(arg.{{ field.name()|var_name }});
size += {{ field|allocation_size_fn }}(arg.{{ field.name()|var_name }});
{%- endfor %}
return size;
}
Expand Down
4 changes: 2 additions & 2 deletions cpp-tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ scaffolding_test_case(fixture_callbacks)
scaffolding_test_case(chronological)
# scaffolding_test_case(custom_types)
scaffolding_test_case(geometry)
# scaffolding_test_case(rondpoint)
scaffolding_test_case(rondpoint)
scaffolding_test_case(sprites)
scaffolding_test_case(todolist)
scaffolding_test_case(traits)
# scaffolding_test_case(coverall)
scaffolding_test_case(coverall)
# scaffolding_test_case(custom_types_builtin)

add_custom_target(libs ALL
Expand Down
285 changes: 285 additions & 0 deletions cpp-tests/scaffolding_tests/coverall/lib_coverall.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,285 @@
#include "lib_coverall.hpp"
#include <chrono>
#include <cstdint>
#include <iostream>
#include <thread>

std::atomic_uint64_t NUM_ALIVE = 0;

coverall::Coveralls::Coveralls(std::string name, bool should_panic) {
if (!should_panic) {
NUM_ALIVE += 1;
this->name = name;
} else {
throw coverall_error::TooManyHoles();
}
}

coverall::Coveralls::Coveralls(std::string name) {
NUM_ALIVE += 1;
this->name = name;
}

coverall::Coveralls::~Coveralls() {
NUM_ALIVE -= 1;
}

bool coverall::IFirst::compare(std::shared_ptr<ISecond> other) {
return false;
}

bool coverall::ISecond::compare(std::shared_ptr<IFirst> other) {
return false;
}

void coverall::ThreadsafeCounter::busy_wait(int32_t ms) {
this->is_busy = true;
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
this->is_busy = false;
}

int32_t coverall::ThreadsafeCounter::increment_if_busy() {
if (this->is_busy) {
return this->count += 1;
} else {
return this->count;
}
}

coverall::Color coverall::Patch::get_color() {
return this->color;
}

std::string coverall::Coveralls::get_name() {
return this->name;
}

bool coverall::Coveralls::maybe_throw(bool should_throw) {
if (should_throw) {
throw coverall_error::TooManyHoles();
} else {
return true;
}
}

// Note: This should test Rust's Into, we don't really have this here
bool coverall::Coveralls::maybe_throw_into(bool should_throw) {
if (should_throw) {
throw coverall_error::TooManyHoles();
} else {
return true;
}
}

bool coverall::Coveralls::maybe_throw_complex(uint8_t input) {
switch(input) {
case 0:
return true;
case 1: {
auto err = complex_error::OsError();
err.code = 10;
err.extended_code = 20;

throw err;
}
case 2: {
auto err = complex_error::PermissionDenied();
err.reason = "Forbidden";

throw err;
}
case 3:
throw complex_error::UnknownError();
default:
throw std::runtime_error("Invalid input");
}
}

void coverall::Coveralls::panic(std::string message) {
throw std::runtime_error("coveralls->panic()");
}

void coverall::Coveralls::fallible_panic(std::string message) {
throw std::runtime_error(message);
}

uint64_t coverall::Coveralls::strong_count(const std::shared_ptr<Coveralls> &self) {
return self.use_count();
}

void coverall::Coveralls::take_other(const std::shared_ptr<Coveralls> &other) {
std::lock_guard<std::mutex> lock(this->other_mutex);
this->other = other;
}

std::shared_ptr<coverall::Coveralls> coverall::Coveralls::get_other() {
std::lock_guard<std::mutex> lock(this->other_mutex);
return this->other;
}

void coverall::Coveralls::take_other_fallible() {
throw coverall::coverall_error::TooManyHoles();
}

void coverall::Coveralls::take_other_panic(std::string message) {
throw std::runtime_error(message);
}

std::shared_ptr<coverall::Coveralls> coverall::Coveralls::clone_me() {
std::lock_guard<std::mutex> lock(this->other_mutex);

auto clone = std::make_shared<Coveralls>(this->name);
clone->other = this->other;

return clone;
}

std::string coverall::Coveralls::get_status(std::string status) {
return "status: " + status;
}

std::unordered_map<std::string, uint64_t> coverall::Coveralls::get_dict(std::string key, uint64_t value) {
std::unordered_map<std::string, uint64_t> map;
map.insert({ key, value });

return map;
}

std::unordered_map<std::string, uint64_t> coverall::Coveralls::get_dict2(std::string key, uint64_t value) {
std::unordered_map<std::string, uint64_t> map;
map.insert({ key, value });

return map;
}

std::unordered_map<uint32_t, uint64_t> coverall::Coveralls::get_dict3(uint32_t key, uint64_t value) {
std::unordered_map<uint32_t, uint64_t> map;
map.insert({ key, value });

return map;
}

void coverall::Coveralls::add_patch(std::shared_ptr<Patch> patch) {
auto repair = Repair {
.when = std::chrono::high_resolution_clock::now(),
.patch = patch
};

std::lock_guard<std::mutex> lock(this->repairs_mutex);
this->repairs.push_back(repair);
}

void coverall::Coveralls::add_repair(Repair repair) {
std::lock_guard<std::mutex> lock(this->repairs_mutex);
this->repairs.push_back(repair);
}

std::vector<coverall::Repair> coverall::Coveralls::get_repairs() {
std::lock_guard<std::mutex> lock(this->repairs_mutex);
return this->repairs;
}

std::vector<uint8_t> coverall::Coveralls::reverse(std::vector<uint8_t> value) {
return std::vector<uint8_t>(value.rbegin(), value.rend());
}


coverall::SimpleDict coverall::create_some_dict() {
std::string some_bytes_string = "some_bytes";
std::string maybe_some_bytes_string = "maybe_some_bytes";

return {
.text = "text",
.maybe_text = "maybe_text",
.some_bytes = std::vector<uint8_t>(some_bytes_string.begin(), some_bytes_string.end()),
.maybe_some_bytes = std::vector<uint8_t>(maybe_some_bytes_string.begin(), maybe_some_bytes_string.end()),
.a_bool = true,
.maybe_a_bool = false,
.unsigned8 = 1,
.maybe_unsigned8 = 2,
.unsigned16 = 3,
.maybe_unsigned16 = 4,
.unsigned64 = std::numeric_limits<uint64_t>::max(),
.maybe_unsigned64 = std::numeric_limits<uint64_t>::min(),
.signed8 = 8,
.maybe_signed8 = 0,
.signed64 = std::numeric_limits<int64_t>::max(),
.maybe_signed64 = 0,
.float32 = 1.2345,
.maybe_float32 = 22.0 / 7.0,
.float64 = 0.0,
.maybe_float64 = 1.0,
.coveralls = std::make_shared<Coveralls>("some_dict"),
.test_trait = nullptr,
};
}

coverall::SimpleDict coverall::create_none_dict() {
return {};
}

uint64_t coverall::get_num_alive() {
return NUM_ALIVE;
}

std::vector<std::shared_ptr<coverall::TestTrait>> coverall::get_traits() {
return {};
}

coverall::MaybeSimpleDict coverall::get_maybe_simple_dict(int8_t index) {
if (index == 0) {
return { coverall::MaybeSimpleDict::YEAH {} };
}
else if (index == 1) {
return { coverall::MaybeSimpleDict::NAH {} };
}

throw std::runtime_error("invalid index");
}

coverall::SimpleFlatMacroEnum coverall::get_simple_flat_macro_enum(int8_t index) {
if (index == 0) {
return { coverall::SimpleFlatMacroEnum::FIRST { "the first" } };
}
else if (index == 1) {
return { coverall::SimpleFlatMacroEnum::SECOND { 2 } };
}

throw std::runtime_error("invalid index");
}

void coverall::println(std::string text) {
std::cout << text << std::endl;
}

void coverall::throw_macro_error() {
throw coverall::coverall_macro_error::TooManyMacros();
}

void coverall::throw_flat_error() {
auto error = coverall::coverall_flat_error::TooManyVariants();
error.num = 99;

throw error;
}

void coverall::throw_flat_macro_error() {
auto error = coverall::coverall_flat_macro_error::TooManyVariants();
error.num = 88;

throw error;
}

void coverall::throw_rich_error_no_variant_data() {
throw coverall::coverall_rich_error_no_variant_data::TooManyPlainVariants();
}

void coverall::throw_complex_macro_error() {
auto error = coverall::complex_macro_error::OsError();
error.code = 1;
error.extended_code = 2;

throw error;
}

#include <coverall_cpp_scaffolding.cpp>
Loading
Loading