summaryrefslogtreecommitdiffstats
path: root/third_party/rust/uniffi_bindgen/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/uniffi_bindgen/src/backend')
-rw-r--r--third_party/rust/uniffi_bindgen/src/backend/config.rs17
-rw-r--r--third_party/rust/uniffi_bindgen/src/backend/filters.rs76
-rw-r--r--third_party/rust/uniffi_bindgen/src/backend/mod.rs11
-rw-r--r--third_party/rust/uniffi_bindgen/src/backend/types.rs78
4 files changed, 182 insertions, 0 deletions
diff --git a/third_party/rust/uniffi_bindgen/src/backend/config.rs b/third_party/rust/uniffi_bindgen/src/backend/config.rs
new file mode 100644
index 0000000000..616cde0656
--- /dev/null
+++ b/third_party/rust/uniffi_bindgen/src/backend/config.rs
@@ -0,0 +1,17 @@
+/* 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/. */
+
+use serde::{Deserialize, Serialize};
+
+/// Config value for template expressions
+///
+/// These are strings that support simple template substitution. `{}` gets replaced by a value.
+#[derive(Debug, Default, Clone, Serialize, Deserialize)]
+pub struct TemplateExpression(String);
+
+impl TemplateExpression {
+ pub fn render(&self, var: &str) -> String {
+ self.0.replace("{}", var)
+ }
+}
diff --git a/third_party/rust/uniffi_bindgen/src/backend/filters.rs b/third_party/rust/uniffi_bindgen/src/backend/filters.rs
new file mode 100644
index 0000000000..0d2da8cab2
--- /dev/null
+++ b/third_party/rust/uniffi_bindgen/src/backend/filters.rs
@@ -0,0 +1,76 @@
+/* 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/. */
+
+//! Backend-agnostic askama filters
+
+use crate::interface::{
+ AsType, CallbackInterface, ComponentInterface, Enum, FfiType, Function, Object, Record,
+};
+use askama::Result;
+use std::fmt;
+
+// Need to define an error that implements std::error::Error, which neither String nor
+// anyhow::Error do.
+#[derive(Debug)]
+struct UniFFIError {
+ message: String,
+}
+
+impl UniFFIError {
+ fn new(message: String) -> Self {
+ Self { message }
+ }
+}
+
+impl fmt::Display for UniFFIError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}", self.message)
+ }
+}
+
+impl std::error::Error for UniFFIError {}
+
+macro_rules! lookup_error {
+ ($($args:tt)*) => {
+ askama::Error::Custom(Box::new(UniFFIError::new(format!($($args)*))))
+ }
+}
+
+/// Get an Enum definition by name
+pub fn get_enum_definition<'a>(ci: &'a ComponentInterface, name: &str) -> Result<&'a Enum> {
+ ci.get_enum_definition(name)
+ .ok_or_else(|| lookup_error!("enum {name} not found"))
+}
+
+/// Get a Record definition by name
+pub fn get_record_definition<'a>(ci: &'a ComponentInterface, name: &str) -> Result<&'a Record> {
+ ci.get_record_definition(name)
+ .ok_or_else(|| lookup_error!("record {name} not found"))
+}
+
+/// Get a Function definition by name
+pub fn get_function_definition<'a>(ci: &'a ComponentInterface, name: &str) -> Result<&'a Function> {
+ ci.get_function_definition(name)
+ .ok_or_else(|| lookup_error!("function {name} not found"))
+}
+
+/// Get an Object definition by name
+pub fn get_object_definition<'a>(ci: &'a ComponentInterface, name: &str) -> Result<&'a Object> {
+ ci.get_object_definition(name)
+ .ok_or_else(|| lookup_error!("object {name} not found"))
+}
+
+/// Get an Callback Interface definition by name
+pub fn get_callback_interface_definition<'a>(
+ ci: &'a ComponentInterface,
+ name: &str,
+) -> Result<&'a CallbackInterface> {
+ ci.get_callback_interface_definition(name)
+ .ok_or_else(|| lookup_error!("callback interface {name} not found"))
+}
+
+/// Get the FfiType for a Type
+pub fn ffi_type(type_: &impl AsType) -> Result<FfiType, askama::Error> {
+ Ok(type_.as_type().into())
+}
diff --git a/third_party/rust/uniffi_bindgen/src/backend/mod.rs b/third_party/rust/uniffi_bindgen/src/backend/mod.rs
new file mode 100644
index 0000000000..6abcfc10d7
--- /dev/null
+++ b/third_party/rust/uniffi_bindgen/src/backend/mod.rs
@@ -0,0 +1,11 @@
+/* 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/. */
+
+mod config;
+pub mod filters;
+mod types;
+
+pub use crate::interface::{Literal, Type};
+pub use config::TemplateExpression;
+pub use types::CodeType;
diff --git a/third_party/rust/uniffi_bindgen/src/backend/types.rs b/third_party/rust/uniffi_bindgen/src/backend/types.rs
new file mode 100644
index 0000000000..3f66fdfe01
--- /dev/null
+++ b/third_party/rust/uniffi_bindgen/src/backend/types.rs
@@ -0,0 +1,78 @@
+/* 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/. */
+
+//! # Backend traits
+//!
+//! A trait to help format items.
+//!
+//! Each backend will have its own `filter` module, which is used by the askama templates.
+use super::Literal;
+use std::fmt::Debug;
+
+// XXX - Note that this trait is not used internally. It exists just to avoid an unnecessary
+// breaking change for external bindings which use this trait.
+// It is likely to be removed some time after 0.26.x.
+
+/// A Trait to help render types in a language specific format.
+pub trait CodeType: Debug {
+ /// The language specific label used to reference this type. This will be used in
+ /// method signatures and property declarations.
+ fn type_label(&self) -> String;
+
+ /// A representation of this type label that can be used as part of another
+ /// identifier. e.g. `read_foo()`, or `FooInternals`.
+ ///
+ /// This is especially useful when creating specialized objects or methods to deal
+ /// with this type only.
+ fn canonical_name(&self) -> String {
+ self.type_label()
+ }
+
+ fn literal(&self, _literal: &Literal) -> String {
+ unimplemented!("Unimplemented for {}", self.type_label())
+ }
+
+ /// Name of the FfiConverter
+ ///
+ /// This is the object that contains the lower, write, lift, and read methods for this type.
+ /// Depending on the binding this will either be a singleton or a class with static methods.
+ ///
+ /// This is the newer way of handling these methods and replaces the lower, write, lift, and
+ /// read CodeType methods. Currently only used by Kotlin, but the plan is to move other
+ /// backends to using this.
+ fn ffi_converter_name(&self) -> String {
+ format!("FfiConverter{}", self.canonical_name())
+ }
+
+ /// An expression for lowering a value into something we can pass over the FFI.
+ fn lower(&self) -> String {
+ format!("{}.lower", self.ffi_converter_name())
+ }
+
+ /// An expression for writing a value into a byte buffer.
+ fn write(&self) -> String {
+ format!("{}.write", self.ffi_converter_name())
+ }
+
+ /// An expression for lifting a value from something we received over the FFI.
+ fn lift(&self) -> String {
+ format!("{}.lift", self.ffi_converter_name())
+ }
+
+ /// An expression for reading a value from a byte buffer.
+ fn read(&self) -> String {
+ format!("{}.read", self.ffi_converter_name())
+ }
+
+ /// A list of imports that are needed if this type is in use.
+ /// Classes are imported exactly once.
+ fn imports(&self) -> Option<Vec<String>> {
+ None
+ }
+
+ /// Function to run at startup
+ fn initialization_fn(&self) -> Option<String> {
+ None
+ }
+}