Skip to content

Commit

Permalink
Normalize case handling for objects and callbacks
Browse files Browse the repository at this point in the history
Objects and callbacks were not handling case consistently in generated
across code, leading to compilation errors in some cases (see #22).

The main problem arises in capital acronym handling, i.e. `HTTPClient`.
Such acronyms are converted using `heck::to_upper_camel_case`, which
converts upper case acronym `HTTP` into upper camel case `Http`, i.e.
`HttpClient`.
  • Loading branch information
arg0d committed Nov 14, 2023
1 parent a3cf5d6 commit f46d8d3
Show file tree
Hide file tree
Showing 14 changed files with 177 additions and 14 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion bindgen/templates/CallbackInterfaceTemplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type {{ type_name }} interface {
// {{ foreign_callback }} cannot be callable be a compiled function at a same time
type {{ foreign_callback }} struct {}

{% let cgo_callback_fn = self.cgo_callback_fn(type_name, module_path) -%}
{% let cgo_callback_fn = self.cgo_callback_fn(cbi.name(), module_path) -%}
//export {{ cgo_callback_fn }}
func {{ cgo_callback_fn }}(handle C.uint64_t, method C.int32_t, argsPtr *C.uint8_t, argsLen C.int32_t, outBuf *C.RustBuffer) C.int32_t {
cb := {{ type_|lift_fn }}(uint64(handle));
Expand Down
10 changes: 5 additions & 5 deletions bindgen/templates/ObjectTemplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,23 @@
{{- self.add_import("runtime") }}

{%- let obj = ci.get_object_definition(name).expect("missing obj") %}
{%- let canonical_name = type_|canonical_name %}
{%- let obj_name = obj.name()|class_name %}
{%- if self.include_once_check("ObjectRuntime.go") %}{% include "ObjectRuntime.go" %}{% endif %}

type {{ canonical_name }} struct {
type {{ obj_name }} struct {
ffiObject FfiObject
}

{%- match obj.primary_constructor() %}
{%- when Some with (cons) %}
func New{{ canonical_name }}({% call go::arg_list_decl(cons) -%}) {% call go::return_type_decl(cons) %} {
func New{{ obj_name }}({% call go::arg_list_decl(cons) -%}) {% call go::return_type_decl(cons) %} {
{% call go::ffi_call_binding(func, "") %}
}
{%- when None %}
{%- endmatch %}

{% for cons in obj.alternate_constructors() -%}
func {{ canonical_name }}{{ cons.name()|fn_name }}({% call go::arg_list_decl(cons) %}) {% call go::return_type_decl(cons) %} {
func {{ obj_name }}{{ cons.name()|fn_name }}({% call go::arg_list_decl(cons) %}) {% call go::return_type_decl(cons) %} {
{% call go::ffi_call_binding(func, "") %}
}
{% endfor %}
Expand Down Expand Up @@ -61,7 +61,7 @@ type {{ obj|ffi_converter_name }} struct {}
var {{ obj|ffi_converter_name }}INSTANCE = {{ obj|ffi_converter_name }}{}

func (c {{ obj|ffi_converter_name }}) Lift(pointer unsafe.Pointer) {{ type_name }} {
result := &{{ canonical_name }} {
result := &{{ obj_name }} {
newFfiObject(
pointer,
func(pointer unsafe.Pointer, status *C.RustCallStatus) {
Expand Down
6 changes: 3 additions & 3 deletions binding_tests/custom_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
package binding_tests

import (
"testing"
"net/url"
"net/url"
"testing"

"github.com/NordSecurity/uniffi-bindgen-go/binding_tests/generated/custom_types"

Expand All @@ -31,6 +31,6 @@ func TestCustomTypes(t *testing.T) {

// Change some data and ensure that the round-trip works
demo.Url = *unwrap(url.Parse("http://new.example.com/"))
demo.Handle = 456;
demo.Handle = 456
assert.Equal(t, demo, custom_types.GetCustomTypesDemo(&demo))
}
30 changes: 30 additions & 0 deletions binding_tests/name_case_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package binding_tests

import (
"errors"
. "github.com/NordSecurity/uniffi-bindgen-go/binding_tests/generated/name_case"
"testing"
)

type MyNameCaseCallback struct{}

func (*MyNameCaseCallback) Test() {}

func TestNameCaseCompiles(t *testing.T) {
_ = EnumTestVariantOne
_ = AssociatedEnumTestVariantTest{0}

var expectedError *ErrorTestVariantOne
errors.As(NewErrorTestVariantOne(), &expectedError)

var expectedAssociatedError *AssociatedErrorTestVariantTest
errors.As(NewAssociatedErrorTestVariantTest(0), &expectedAssociatedError)

var _ *ObjectTest = NewObjectTest()
_ = RecordTest{0}
var _ CallbackTest = &MyNameCaseCallback{}
}
2 changes: 1 addition & 1 deletion docker_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ docker run \
--volume $HOME/.cargo/registry:/usr/local/cargo/registry \
--volume $PWD:/mounted_workdir \
--workdir /mounted_workdir \
rust:1.64 ./build.sh
rust:1.70 ./build.sh
4 changes: 2 additions & 2 deletions fixtures/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ uniffi-fixture-type-limits = { path = "../3rd-party/uniffi-rs/fixtures/type-limi
uniffi-fixture-time = { path = "../3rd-party/uniffi-rs/fixtures/uniffi-fixture-time" }

# Go specific
uniffi-go-fixture-errors = { path = "errors" }
uniffi-go-fixture-destroy = { path = "destroy" }
uniffi-go-fixture-errors = { path = "errors" }
uniffi-go-fixture-name-case = { path = "name-case" }
uniffi-go-fixture-objects = { path = "objects" }

2 changes: 1 addition & 1 deletion fixtures/destroy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub struct SmallJournal {

#[derive(Debug, Clone)]
pub enum EnumJournal {
Journal { journal: SmallJournal }
Journal { journal: SmallJournal },
}

fn create_journal() -> ResourceJournal {
Expand Down
24 changes: 24 additions & 0 deletions fixtures/name-case/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[package]
name = "uniffi-go-fixture-name-case"
version = "0.22.0"
authors = ["Firefox Sync Team <[email protected]>"]
edition = "2021"
license = "MPL-2.0"
publish = false

[lib]
name = "uniffi_go_name_case"
crate-type = ["lib", "cdylib"]

[dependencies]
thiserror = "1.0"
uniffi = { path = "../../3rd-party/uniffi-rs/uniffi" }

[build-dependencies]
uniffi = {path = "../../3rd-party/uniffi-rs/uniffi", features = ["build"] }

[dev-dependencies]
glob = "0.3"
uniffi = {path = "../../3rd-party/uniffi-rs/uniffi", features = ["bindgen-tests"] }
uniffi_bindgen = { path = "../../3rd-party/uniffi-rs/uniffi_bindgen" }
uniffi_testing = { path = "../../3rd-party/uniffi-rs/uniffi_testing" }
3 changes: 3 additions & 0 deletions fixtures/name-case/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# A basic test for uniffi components

This test covers case senstitivity for generate code.
7 changes: 7 additions & 0 deletions fixtures/name-case/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

fn main() {
uniffi::generate_scaffolding("./src/name-case.udl").unwrap();
}
51 changes: 51 additions & 0 deletions fixtures/name-case/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

include!(concat!(env!("OUT_DIR"), "/name-case.uniffi.rs"));

pub enum ENUMTest {
VARIANTOne,
}

pub enum AssociatedENUMTest {
VARIANTTest { code: i16 },
}

#[derive(Debug, thiserror::Error)]
pub enum ERRORTest {
#[error("Test")]
VARIANTOne,
}

#[derive(Debug, thiserror::Error)]
pub enum AssociatedERRORTest {
#[error("Test")]
VARIANTTest { code: i16 },
}

pub struct OBJECTTest {}

impl OBJECTTest {
pub fn new() -> Self {
OBJECTTest {}
}

pub fn new_alternate() -> Self {
OBJECTTest {}
}

pub fn test(&self) {}
}

pub struct RECORDTest {
test: i32,
}

pub fn test() {
let _ = ERRORTest::VARIANTOne;
}

pub trait CALLBACKTest {
fn test(&self);
}
35 changes: 35 additions & 0 deletions fixtures/name-case/src/name-case.udl
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
namespace name_case {
void test();
};

enum ENUMTest { "VARIANTOne" };

[Enum]
interface AssociatedENUMTest {
VARIANTTest(i16 code);
};

[Error]
enum ERRORTest { "VARIANTOne" };

[Error]
interface AssociatedERRORTest {
VARIANTTest(i16 code);
};

interface OBJECTTest {
constructor();

[Name="new_alternate"]
constructor();

void test();
};

dictionary RECORDTest {
i32 test;
};

callback interface CALLBACKTest {
void test();
};
3 changes: 2 additions & 1 deletion fixtures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ mod uniffi_fixtures {
uniffi_type_limits::uniffi_reexport_scaffolding!();

// Go specific
uniffi_go_errors::uniffi_reexport_scaffolding!();
uniffi_go_destroy::uniffi_reexport_scaffolding!();
uniffi_go_errors::uniffi_reexport_scaffolding!();
uniffi_go_name_case::uniffi_reexport_scaffolding!();
uniffi_go_objects::uniffi_reexport_scaffolding!();
}

0 comments on commit f46d8d3

Please sign in to comment.