Builder pattern with uniffi
⚓ Rust 📅 2025-10-01 👤 surdeus 👁️ 19Trying to implement a builder pattern in Rust to be used in Swift with UniFFI but i found a sharp edge which is this one
A regular builder pattern would be like this:
pub struct MyThingBuilder {
field1: Option<String>,
field2: Option<u32>,
}
impl MyThingBuilder {
pub fn new() -> Self {
Self {
field1: None,
field2: None,
}
}
pub fn field1(mut self, val: String) -> Self {
self.field1 = Some(val);
self
}
pub fn field2(mut self, val: u32) -> Self {
self.field2 = Some(val);
self
}
pub fn build(self) -> MyThing {
MyThing {
field1: self.field1.unwrap_or_default(),
field2: self.field2.unwrap_or_default(),
}
}
}
But returning self each time seems to be incompatible with UniFFI. Therefor the solution i get from clankers is to write it like this:
use std::sync::Arc;
pub struct MyThing {
pub field1: String,
pub field2: u32,
}
pub struct MyThingBuilder {
field1: Option<String>,
field2: Option<u32>,
}
impl MyThingBuilder {
pub fn new() -> Arc<Self> {
Arc::new(Self {
field1: None,
field2: None,
})
}
pub fn field1(self: Arc<Self>, val: String) -> Arc<Self> {
let mut new = (*self).clone();
new.field1 = Some(val);
Arc::new(new)
}
pub fn field2(self: Arc<Self>, val: u32) -> Arc<Self> {
let mut new = (*self).clone();
new.field2 = Some(val);
Arc::new(new)
}
pub fn build(self: Arc<Self>) -> MyThing {
MyThing {
field1: self.field1.clone().unwrap_or_default(),
field2: self.field2.unwrap_or_default(),
}
}
}
impl Clone for MyThingBuilder {
fn clone(&self) -> Self {
Self {
field1: self.field1.clone(),
field2: self.field2,
}
}
}
Is there a cleaner way of getting this working with UniFFI without cloning each time i return data per chaining? Am i missing something?
2 posts - 2 participants
🏷️ Rust_feed