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

Migrate from askama to rinja #155

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ resolver = "2"

[workspace.dependencies]
anyhow = "1"
askama = "0.12.1"
rinja = "0.3.5"
camino = "1.1.6"
cargo_metadata = "0.15"
clap = { version = "4.5.4", features = ["derive"] }
Expand Down
2 changes: 1 addition & 1 deletion crates/ubrn_bindgen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ edition = "2021"

[dependencies]
anyhow = { workspace = true }
askama = { workspace = true }
rinja = { workspace = true }
camino = { workspace = true }
clap = { workspace = true }
heck = { workspace = true }
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion crates/ubrn_bindgen/src/bindings/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub(crate) mod type_map;
use std::{fs, str::FromStr};

use anyhow::Result;
use askama::Template;
use rinja::Template;
use camino::{Utf8Path, Utf8PathBuf};
use clap::{command, Args};
use ubrn_common::{mk_dir, CrateMetadata};
Expand Down
18 changes: 9 additions & 9 deletions crates/ubrn_bindgen/src/bindings/react_native/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::react_native::{ComponentInterfaceExt, FfiTypeExt};

pub fn ffi_type_name_from_js(ffi_type: &FfiType) -> Result<String, askama::Error> {
pub fn ffi_type_name_from_js(ffi_type: &FfiType) -> Result<String, rinja::Error> {
Ok(match ffi_type {
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, askama::Error> {
pub fn cpp_namespace(ffi_type: &FfiType, ci: &ComponentInterface) -> Result<String, rinja::Error> {
Ok(ffi_type.cpp_namespace(ci))
}

pub fn bridging_namespace(
ffi_type: &FfiType,
ci: &ComponentInterface,
) -> Result<String, askama::Error> {
) -> Result<String, rinja::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 @@ -39,17 +39,17 @@ pub fn bridging_namespace(
pub fn bridging_class(
ffi_type: &FfiType,
ci: &ComponentInterface,
) -> Result<String, askama::Error> {
) -> Result<String, rinja::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, askama::Error> {
pub fn ffi_type_name_to_rust(ffi_type: &FfiType) -> Result<String, rinja::Error> {
ffi_type_name(ffi_type)
}

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

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

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

pub fn ffi_struct_name(nm: &str) -> Result<String, askama::Error> {
pub fn ffi_struct_name(nm: &str) -> Result<String, rinja::Error> {
Ok(format!("Uniffi{}", nm.to_upper_camel_case()))
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::bindings::{
},
};
use anyhow::Result;
use askama::Template;
use rinja::Template;
use std::borrow::Borrow;
use uniffi_bindgen::interface::{FfiDefinition, FfiType};
use uniffi_bindgen::ComponentInterface;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,31 @@ use uniffi_bindgen::{
pub(super) fn type_name(
as_type: &impl AsType,
types: &TypeRenderer,
) -> Result<String, askama::Error> {
) -> Result<String, rinja::Error> {
let type_ = types.as_type(as_type);
Ok(type_.as_codetype().type_label(types.ci))
}

pub(super) fn decl_type_name(
as_type: &impl AsType,
types: &TypeRenderer,
) -> Result<String, askama::Error> {
) -> Result<String, rinja::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, askama::Error> {
) -> Result<String, rinja::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, askama::Error> {
) -> Result<String, rinja::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 @@ -57,7 +57,7 @@ pub(super) fn ffi_error_converter_name(
pub(super) fn lower_error_fn(
as_type: &impl AsType,
types: &TypeRenderer,
) -> Result<String, askama::Error> {
) -> Result<String, rinja::Error> {
Ok(format!(
"{ct}.lower.bind({ct})",
ct = ffi_error_converter_name(as_type, types)?
Expand All @@ -67,7 +67,7 @@ pub(super) fn lower_error_fn(
pub(super) fn lift_error_fn(
as_type: &impl AsType,
types: &TypeRenderer,
) -> Result<String, askama::Error> {
) -> Result<String, rinja::Error> {
Ok(format!(
"{ct}.lift.bind({ct})",
ct = ffi_error_converter_name(as_type, types)?
Expand All @@ -77,7 +77,7 @@ pub(super) fn lift_error_fn(
pub(super) fn lift_fn(
as_type: &impl AsType,
types: &TypeRenderer,
) -> Result<String, askama::Error> {
) -> Result<String, rinja::Error> {
Ok(format!(
"{ct}.lift.bind({ct})",
ct = ffi_converter_name(as_type, types)?
Expand All @@ -88,15 +88,15 @@ pub fn render_literal(
literal: &Literal,
as_ct: &impl AsType,
ci: &ComponentInterface,
) -> Result<String, askama::Error> {
) -> Result<String, rinja::Error> {
Ok(as_ct.as_codetype().literal(literal, ci))
}

pub fn variant_discr_literal(
e: &Enum,
index: &usize,
ci: &ComponentInterface,
) -> Result<String, askama::Error> {
) -> Result<String, rinja::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 @@ -127,60 +127,60 @@ pub fn variant_discr_literal(
})
}

pub fn ffi_type_name_for_cpp(type_: &FfiType, is_internal: &bool) -> Result<String, askama::Error> {
pub fn ffi_type_name_for_cpp(type_: &FfiType, is_internal: &bool) -> Result<String, rinja::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, askama::Error> {
pub fn ffi_type_name(ffi_type: &FfiType) -> Result<String, rinja::Error> {
Ok(CodeOracle.ffi_type_label(ffi_type))
}

pub fn ffi_default_value(type_: &FfiType) -> Result<String, askama::Error> {
pub fn ffi_default_value(type_: &FfiType) -> Result<String, rinja::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, askama::Error> {
pub fn class_name(nm: &str, ci: &ComponentInterface) -> Result<String, rinja::Error> {
Ok(CodeOracle.class_name(ci, nm))
}

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

/// Get the idiomatic Typescript rendering of a variable name.
pub fn var_name(nm: &str) -> Result<String, askama::Error> {
pub fn var_name(nm: &str) -> Result<String, rinja::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, askama::Error> {
pub fn arg_name(nm: &str) -> Result<String, rinja::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, askama::Error> {
pub fn variant_name(v: &Variant) -> Result<String, rinja::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, askama::Error> {
pub fn ffi_callback_name(nm: &str) -> Result<String, rinja::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, askama::Error> {
pub fn ffi_struct_name(nm: &str) -> Result<String, rinja::Error> {
Ok(CodeOracle.ffi_struct_name(nm))
}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ mod primitives;
mod record;

use anyhow::{Context, Result};
use askama::Template;
use rinja::Template;
use filters::{ffi_converter_name, type_name};
use heck::ToUpperCamelCase;
use oracle::CodeOracle;
Expand Down Expand Up @@ -164,7 +164,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 askama `{{ }}` block.
// Returns an empty string so that it can be used inside a rinja `{{ }}` 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 @@ -29,7 +29,7 @@ const {{ trait_impl }}: { vtable: {{ vtable|ffi_type_name }}; register: () => vo
{%- endif %}
: {% call ts::return_type(meth) %} => {
const jsCallback = {{ ffi_converter_name }}.lift(uniffiHandle);
return {% call ts::await(meth) %}jsCallback.{{ meth.name()|fn_name }}(
return {% call ts::is_await(meth) %}jsCallback.{{ meth.name()|fn_name }}(
{%- for arg in meth.arguments() %}
{{ arg|ffi_converter_name(self) }}.lift({{ arg.name()|var_name }}){% if !loop.last %}, {% endif %}
{%- endfor %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
// Internal macro common to method_decl and top_func_decl
{%- macro func_decl(prefix, func_decl, obj_factory, callable, indent) %}
{%- call docstring(callable, indent) %}
{{ prefix }}{% call async(callable) %}{{ func_decl }} {{ callable.name()|fn_name }}(
{{ prefix }}{% call is_async(callable) %}{{ func_decl }} {{ callable.name()|fn_name }}(
{%- call arg_list_decl(callable) -%}): {# space #}

{%- call return_type(callable) %}
Expand Down Expand Up @@ -237,19 +237,19 @@
{%- endif %}
{%- endmacro %}

{%- macro async(func) %}
{%- macro is_async(func) %}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This renaming and the ones below are required because rinja doesn't allow Rust keywords as macro names. I'm not sure if the names are particularly great but this follows what uniffi-rs itself does.

{%- if func.is_async() %}async {% endif %}
{%- endmacro -%}

{%- macro await(func) %}
{%- macro is_await(func) %}
{%- if func.is_async() %}await {% endif %}
{%- endmacro -%}

{%- macro throws(func) %}
{%- if func.throws() %} /*throws*/{% endif %}
{%- endmacro -%}

{%- macro try(func) %}
{%- macro is_try(func) %}
{%- if func.throws() %}/*try*/ {% else %}/*try!*/ {% endif %}
{%- endmacro -%}

Expand Down
2 changes: 1 addition & 1 deletion crates/ubrn_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ name = "uniffi-bindgen-react-native"

[dependencies]
anyhow = { workspace = true }
askama = { workspace = true }
rinja = { workspace = true }
camino = { workspace = true }
clap = { workspace = true }
heck = { 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 @@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/
*/
use anyhow::Result;
use askama::DynTemplate;
use rinja::DynTemplate;
use camino::{Utf8Path, Utf8PathBuf};
use clap::Args;
use std::{cell::OnceCell, collections::BTreeMap, rc::Rc};
Expand Down Expand Up @@ -137,7 +137,7 @@ fn render_templates(
macro_rules! templated_file {
($T:ty, $filename:literal) => {
paste::paste! {
#[derive(askama::Template)]
#[derive(rinja::Template)]
#[template(path = $filename, escape = "none")]
pub(crate) struct $T {
#[allow(dead_code)]
Expand Down
2 changes: 1 addition & 1 deletion docs/src/contributing/changing-bindings-templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ The central workings of a `uniffi-bingen` are its templates.
- [Typescript templates][ts-templates]
- [C++ templates][cpp-templates]

Templates are written for [Askama templating library](https://djc.github.io/askama/template_syntax.html).
Templates are written for [Rinja templating library](https://rinja.readthedocs.io/en/stable/template_syntax.html).

There is a small-ish runtime for both languages:

Expand Down
2 changes: 1 addition & 1 deletion docs/src/contributing/changing-turbo-module-templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

In addition to generating the bindings between Hermes and Rust, `uniffi-bindgen-react-native` generates the files needed to run this as a turbo-module. The list of files are [documented elsewhere in this book](../reference/turbo-module-files.md).

Templates are written for [Askama templating library](https://djc.github.io/askama/template_syntax.html).
Templates are written for [Rinja templating library](https://rinja.readthedocs.io/en/stable/template_syntax.html).

Changing the templates for these files is relatively simple. [This PR is a good example](https://github.com/jhugman/uniffi-bindgen-react-native/pull/112) of adding a file.

Expand Down
Loading