Skip to content

Add reproduction for uniffi arc objects #241

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

Merged
merged 6 commits into from
Jun 9, 2025
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
10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ resolver = "2"

[workspace.dependencies]
anyhow = "1"
askama = "0.13.1"
camino = "1.1.6"
cargo_metadata = "0.15"
cargo_metadata = "0.19.2"
clap = { version = "4.5.4", features = ["derive"] }
extend = "1.2.0"
heck = "0.5.0"
paste = "1.0.14"
pathdiff = { version = "0.2.1", features = ["camino"] }
rinja = "0.3.5"
serde = { version = "1", features = ["derive"] }
toml = "0.8.22"
uniffi = "=0.29.0"
uniffi_bindgen = "=0.29.0"
uniffi_meta = "=0.29.0"
uniffi = "=0.29.3"
uniffi_bindgen = "=0.29.3"
uniffi_meta = "=0.29.3"
2 changes: 1 addition & 1 deletion crates/ubrn_bindgen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ wasm = ["quote", "prettyplease", "syn", "proc-macro2"]

[dependencies]
anyhow = { workspace = true }
askama = { workspace = true }
camino = { workspace = true }
cargo_metadata = { workspace = true }
clap = { workspace = true }
extend = { workspace = true }
heck = { workspace = true }
paste = { workspace = true }
rinja = { workspace = true }
serde = { workspace = true }
textwrap = "0.16.1"
toml = "0.5"
Expand Down
File renamed without changes.
21 changes: 12 additions & 9 deletions crates/ubrn_bindgen/src/bindings/gen_cpp/filters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@ use uniffi_bindgen::{interface::FfiType, ComponentInterface};

use crate::bindings::extensions::{ComponentInterfaceExt, FfiTypeExt};

pub fn ffi_type_name_from_js(ffi_type: &FfiType) -> Result<String, rinja::Error> {
pub fn ffi_type_name_from_js(ffi_type: &FfiType) -> Result<String, askama::Error> {
Ok(match ffi_type {
FfiType::MutReference(inner) | FfiType::Reference(inner) => ffi_type_name_from_js(inner)?,
_ => ffi_type_name(ffi_type)?,
})
}

pub fn cpp_namespace(ffi_type: &FfiType, ci: &ComponentInterface) -> Result<String, rinja::Error> {
pub fn cpp_namespace(ffi_type: &FfiType, ci: &ComponentInterface) -> Result<String, askama::Error> {
Ok(ffi_type.cpp_namespace(ci))
}

pub fn bridging_namespace(
ffi_type: &FfiType,
ci: &ComponentInterface,
) -> Result<String, rinja::Error> {
) -> Result<String, askama::Error> {
// Bridging types are only in the uniffi_jsi namespace (`ci.cpp_namespace_includes()`)
// or the generated namespace. Most of the time, `ffi_type.cpp_namespace()` does
// the right thing, except in the case of Callbacks and Structs.
Expand All @@ -36,17 +36,20 @@ pub fn bridging_namespace(
})
}

pub fn bridging_class(ffi_type: &FfiType, ci: &ComponentInterface) -> Result<String, rinja::Error> {
pub fn bridging_class(
ffi_type: &FfiType,
ci: &ComponentInterface,
) -> Result<String, askama::Error> {
let ns = bridging_namespace(ffi_type, ci)?;
let type_name = ffi_type_name_from_js(ffi_type)?;
Ok(format!("{ns}::Bridging<{type_name}>"))
}

pub fn ffi_type_name_to_rust(ffi_type: &FfiType) -> Result<String, rinja::Error> {
pub fn ffi_type_name_to_rust(ffi_type: &FfiType) -> Result<String, askama::Error> {
ffi_type_name(ffi_type)
}

pub fn ffi_type_name(ffi_type: &FfiType) -> Result<String, rinja::Error> {
pub fn ffi_type_name(ffi_type: &FfiType) -> Result<String, askama::Error> {
Ok(match ffi_type {
FfiType::UInt8 => "uint8_t".into(),
FfiType::Int8 => "int8_t".into(),
Expand All @@ -72,14 +75,14 @@ pub fn ffi_type_name(ffi_type: &FfiType) -> Result<String, rinja::Error> {
})
}

pub fn var_name(nm: &str) -> Result<String, rinja::Error> {
pub fn var_name(nm: &str) -> Result<String, askama::Error> {
Ok(nm.to_lower_camel_case())
}

pub fn ffi_callback_name(nm: &str) -> Result<String, rinja::Error> {
pub fn ffi_callback_name(nm: &str) -> Result<String, askama::Error> {
Ok(format!("Uniffi{}", nm.to_upper_camel_case()))
}

pub fn ffi_struct_name(nm: &str) -> Result<String, rinja::Error> {
pub fn ffi_struct_name(nm: &str) -> Result<String, askama::Error> {
Ok(format!("Uniffi{}", nm.to_upper_camel_case()))
}
2 changes: 1 addition & 1 deletion crates/ubrn_bindgen/src/bindings/gen_cpp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ mod util;
use std::borrow::Borrow;

use anyhow::Result;
use rinja::Template;
use askama::Template;
use ubrn_common::CrateMetadata;
use uniffi_bindgen::interface::{FfiDefinition, FfiType};
use uniffi_bindgen::ComponentInterface;
Expand Down
15 changes: 11 additions & 4 deletions crates/ubrn_bindgen/src/bindings/gen_typescript/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ use std::collections::HashMap;

use serde::{Deserialize, Serialize};

use uniffi_bindgen::backend::TemplateExpression;

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub(crate) struct TsConfig {
Expand Down Expand Up @@ -54,7 +52,16 @@ pub(crate) struct CustomTypeConfig {
pub(crate) imports: Vec<(String, String)>,
pub(crate) type_name: Option<String>,
#[serde(alias = "lift")]
pub(crate) into_custom: TemplateExpression,
pub(crate) into_custom: String,
#[serde(alias = "lower")]
pub(crate) from_custom: TemplateExpression,
pub(crate) from_custom: String,
}

impl CustomTypeConfig {
pub(crate) fn lift(&self, variable: &str) -> String {
self.into_custom.replace("{}", variable)
}
pub(crate) fn lower(&self, variable: &str) -> String {
self.from_custom.replace("{}", variable)
}
}
45 changes: 24 additions & 21 deletions crates/ubrn_bindgen/src/bindings/gen_typescript/filters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ use uniffi_bindgen::{
pub(super) fn type_name(
as_type: &impl AsType,
types: &TypeRenderer,
) -> Result<String, rinja::Error> {
) -> Result<String, askama::Error> {
let type_ = types.as_type(as_type);
Ok(type_.as_codetype().type_label(types.ci))
}

pub(super) fn ffi_type_name_from_type(
as_type: &impl AsType,
types: &TypeRenderer,
) -> Result<String, rinja::Error> {
) -> Result<String, askama::Error> {
let type_ = types.as_type(as_type);
let ffi_type = FfiType::from(type_);
ffi_type_name(&ffi_type)
Expand All @@ -34,23 +34,23 @@ pub(super) fn ffi_type_name_from_type(
pub(super) fn decl_type_name(
as_type: &impl AsType,
types: &TypeRenderer,
) -> Result<String, rinja::Error> {
) -> Result<String, askama::Error> {
let type_ = types.as_type(as_type);
Ok(type_.as_codetype().decl_type_label(types.ci))
}

pub(super) fn ffi_converter_name(
as_type: &impl AsType,
types: &TypeRenderer,
) -> Result<String, rinja::Error> {
) -> Result<String, askama::Error> {
let type_ = types.as_type(as_type);
Ok(type_.as_codetype().ffi_converter_name())
}

pub(super) fn ffi_error_converter_name(
as_type: &impl AsType,
types: &TypeRenderer,
) -> Result<String, rinja::Error> {
) -> Result<String, askama::Error> {
// special handling for types used as errors.
let type_ = types.as_type(as_type);
let mut name = type_.as_codetype().ffi_converter_name();
Expand All @@ -73,7 +73,7 @@ pub(super) fn ffi_error_converter_name(
pub(super) fn lower_error_fn(
as_type: &impl AsType,
types: &TypeRenderer,
) -> Result<String, rinja::Error> {
) -> Result<String, askama::Error> {
Ok(format!(
"{ct}.lower.bind({ct})",
ct = ffi_error_converter_name(as_type, types)?
Expand All @@ -83,14 +83,17 @@ pub(super) fn lower_error_fn(
pub(super) fn lift_error_fn(
as_type: &impl AsType,
types: &TypeRenderer,
) -> Result<String, rinja::Error> {
) -> Result<String, askama::Error> {
Ok(format!(
"{ct}.lift.bind({ct})",
ct = ffi_error_converter_name(as_type, types)?
))
}

pub(super) fn lift_fn(as_type: &impl AsType, types: &TypeRenderer) -> Result<String, rinja::Error> {
pub(super) fn lift_fn(
as_type: &impl AsType,
types: &TypeRenderer,
) -> Result<String, askama::Error> {
Ok(format!(
"{ct}.lift.bind({ct})",
ct = ffi_converter_name(as_type, types)?
Expand All @@ -101,15 +104,15 @@ pub fn render_literal(
literal: &Literal,
as_ct: &impl AsType,
ci: &ComponentInterface,
) -> Result<String, rinja::Error> {
) -> Result<String, askama::Error> {
Ok(as_ct.as_codetype().literal(literal, ci))
}

pub fn variant_discr_literal(
e: &Enum,
index: &usize,
ci: &ComponentInterface,
) -> Result<String, rinja::Error> {
) -> Result<String, askama::Error> {
let literal = e.variant_discr(*index).expect("invalid index");
let ts_literal = Type::Int32.as_codetype().literal(&literal, ci);
Ok(match literal {
Expand Down Expand Up @@ -140,60 +143,60 @@ pub fn variant_discr_literal(
})
}

pub fn ffi_type_name_for_cpp(type_: &FfiType, is_internal: &bool) -> Result<String, rinja::Error> {
pub fn ffi_type_name_for_cpp(type_: &FfiType, is_internal: &bool) -> Result<String, askama::Error> {
Ok(if *is_internal {
CodeOracle.ffi_type_label_for_cpp(type_)
} else {
CodeOracle.ffi_type_label(type_)
})
}

pub fn ffi_type_name(ffi_type: &FfiType) -> Result<String, rinja::Error> {
pub fn ffi_type_name(ffi_type: &FfiType) -> Result<String, askama::Error> {
Ok(CodeOracle.ffi_type_label(ffi_type))
}

pub fn ffi_default_value(type_: &FfiType) -> Result<String, rinja::Error> {
pub fn ffi_default_value(type_: &FfiType) -> Result<String, askama::Error> {
Ok(CodeOracle.ffi_default_value(type_))
}

/// Get the idiomatic Typescript rendering of a function name.
pub fn class_name(nm: &str, ci: &ComponentInterface) -> Result<String, rinja::Error> {
pub fn class_name(nm: &str, ci: &ComponentInterface) -> Result<String, askama::Error> {
Ok(CodeOracle.class_name(ci, nm))
}

/// Get the idiomatic Typescript rendering of a function name.
pub fn fn_name(nm: &str) -> Result<String, rinja::Error> {
pub fn fn_name(nm: &str) -> Result<String, askama::Error> {
Ok(CodeOracle.fn_name(nm))
}

/// Get the idiomatic Typescript rendering of a variable name.
pub fn var_name(nm: &str) -> Result<String, rinja::Error> {
pub fn var_name(nm: &str) -> Result<String, askama::Error> {
Ok(CodeOracle.var_name(nm))
}

/// Get the idiomatic Swift rendering of an arguments name.
/// This is the same as the var name but quoting is not required.
pub fn arg_name(nm: &str) -> Result<String, rinja::Error> {
pub fn arg_name(nm: &str) -> Result<String, askama::Error> {
Ok(CodeOracle.var_name(nm))
}

/// Get a String representing the name used for an individual enum variant.
pub fn variant_name(v: &Variant) -> Result<String, rinja::Error> {
pub fn variant_name(v: &Variant) -> Result<String, askama::Error> {
Ok(CodeOracle.enum_variant_name(v.name()))
}

/// Get the idiomatic Typescript rendering of an FFI callback function name
pub fn ffi_callback_name(nm: &str) -> Result<String, rinja::Error> {
pub fn ffi_callback_name(nm: &str) -> Result<String, askama::Error> {
Ok(CodeOracle.ffi_callback_name(nm))
}

/// Get the idiomatic Typescript rendering of an FFI struct name
pub fn ffi_struct_name(nm: &str) -> Result<String, rinja::Error> {
pub fn ffi_struct_name(nm: &str) -> Result<String, askama::Error> {
Ok(CodeOracle.ffi_struct_name(nm))
}

/// Get the idiomatic Typescript rendering of docstring
pub fn docstring(docstring: &str, spaces: &i32) -> Result<String, rinja::Error> {
pub fn docstring(docstring: &str, spaces: &i32) -> Result<String, askama::Error> {
let middle = textwrap::indent(&textwrap::dedent(docstring), " * ");
let wrapped = format!("/**\n{middle}\n */");

Expand Down
4 changes: 2 additions & 2 deletions crates/ubrn_bindgen/src/bindings/gen_typescript/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ use std::cell::RefCell;
use std::collections::{BTreeMap, BTreeSet, HashSet};

use anyhow::{Context, Result};
use askama::Template;
use heck::ToUpperCamelCase;
use rinja::Template;
use uniffi_bindgen::interface::{AsType, Callable, FfiDefinition, FfiType, Type, UniffiTrait};
use uniffi_bindgen::ComponentInterface;

Expand Down Expand Up @@ -208,7 +208,7 @@ impl<'a> TypeRenderer<'a> {
// import { foo } from "uniffi-bindgen-react-native/bar"
// ```
//
// Returns an empty string so that it can be used inside an rinja `{{ }}` block.
// Returns an empty string so that it can be used inside an askama `{{ }}` block.
fn import_infra(&self, what: &str, _from: &str) -> &str {
self.add_import(
Imported::JSType(what.to_owned()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,22 @@ const {{ ffi_converter_name }} = (() => {
class FFIConverter implements FfiConverter<FfiType, TsType> {
lift(value: FfiType): TsType {
const intermediate = intermediateConverter.lift(value);
return {{ config.into_custom.render("intermediate") }};
return {{ config.lift("intermediate") }};
}
lower(value: TsType): FfiType {
const intermediate = {{ config.from_custom.render("value") }};
const intermediate = {{ config.lower("value") }};
return intermediateConverter.lower(intermediate);
}
read(from: RustBuffer): TsType {
const intermediate = intermediateConverter.read(from);
return {{ config.into_custom.render("intermediate") }};
return {{ config.lift("intermediate") }};
}
write(value: TsType, into: RustBuffer): void {
const intermediate = {{ config.from_custom.render("value") }};
const intermediate = {{ config.lower("value") }};
intermediateConverter.write(intermediate, into);
}
allocationSize(value: TsType): number {
const intermediate = {{ config.from_custom.render("value") }};
const intermediate = {{ config.lower("value") }};
return intermediateConverter.allocationSize(intermediate);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function uniffiEnsureInitialized() {
}
{%- endfor %}

{% for fn in self.initialization_fns() -%}
{{ fn }}();
{% for func in self.initialization_fns() -%}
{{ func }}();
{% endfor -%}
}
2 changes: 1 addition & 1 deletion crates/ubrn_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ wasm = []

[dependencies]
anyhow = { workspace = true }
rinja = { workspace = true }
askama = { workspace = true }
camino = { workspace = true }
clap = { workspace = true }
extend = { workspace = true }
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions crates/ubrn_cli/src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
use std::{cell::OnceCell, collections::BTreeMap, rc::Rc};

use anyhow::Result;
use askama::DynTemplate;
use camino::{Utf8Path, Utf8PathBuf};
use rinja::DynTemplate;

use ubrn_bindgen::ModuleMetadata;
use ubrn_common::{mk_dir, CrateMetadata};
Expand Down Expand Up @@ -111,7 +111,7 @@ fn render_templates(
macro_rules! templated_file {
($T:ty, $filename:literal) => {
paste::paste! {
#[derive(rinja::Template)]
#[derive(askama::Template)]
#[template(path = $filename, escape = "none")]
pub(crate) struct $T {
#[allow(dead_code)]
Expand Down
Loading